home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #12 / Amiga Plus CD - 2002 - No. 12.iso / Games / saga / source / saga.c < prev    next >
C/C++ Source or Header  |  2002-11-04  |  287KB  |  7,023 lines

  1. #include <exec/exec.h>
  2. #include <intuition/intuition.h>
  3. #include <utility/tagitem.h>
  4. #include <graphics/gfx.h>
  5. #include <clib/intuition_protos.h> // Object
  6. #include <libraries/gadtools.h>    // struct NewMenu
  7. #include <devices/timer.h>         // struct timeval
  8. #include <clib/timer_protos.h>
  9. #include <dos/dosextens.h>         // struct Process
  10. #include <libraries/asl.h>         // ASL_FileRequest
  11. #include <dos/dostags.h>           // SYS_Output
  12. #include <dos/datetime.h>          // struct DateTime
  13. #include <clib/dos_protos.h>
  14. #include <libraries/locale.h>
  15. #define OLD_GRAPHICS_GFXMACROS_H
  16. #include <graphics/gfxmacros.h>
  17. #include <hardware/custom.h>
  18. #include <hardware/dmabits.h>
  19.  
  20. #include <stdlib.h> /* EXIT_SUCCESS, EXIT_FAILURE */
  21. #include <assert.h>
  22.  
  23. #include "saga.h"
  24.  
  25. #define CATCOMP_NUMBERS
  26. #define CATCOMP_CODE
  27. #define CATCOMP_BLOCK
  28. #include "saga_strings.h"
  29.  
  30. // #define ASSERT
  31.  
  32. #define NORMAL           0
  33. #define GOOD             1
  34. #define BAD              2
  35.  
  36. #define TURNS           20
  37.  
  38. #define UPPER            0
  39. #define LOWER            1
  40.  
  41. #define SCOREDISTANCE   13
  42.  
  43. #define MESSAGEY       473
  44.  
  45. #define AMSIR            0
  46. #define EON              1
  47. #define GEOFU            2
  48. #define ING              3
  49. #define OGAL             4
  50. #define SYGIL            5
  51.  
  52. #define HAGALL           1
  53. #define IS               2
  54. #define JARA             3
  55. #define NIED             4
  56. #define WYNN             5
  57. #define YR               6
  58.  
  59. #define KEYBOARD         0
  60. #define COUNTRY          1
  61. #define COUNTER          2
  62. #define ANYKEY           3
  63.         
  64. // scancodes
  65. #define SCAN_F1         80
  66. #define SCAN_F2         81
  67. #define SCAN_F3         82
  68. #define SCAN_F4         83
  69. #define SCAN_F5         84
  70. #define SCAN_F6         85
  71. #define HELP            95
  72. #define FIRSTQUALIFIER  96
  73. #define LASTQUALIFIER  103
  74. #define KEYUP          128 /* key release */
  75.  
  76. #define BLACK            0
  77. #define WHITE            1
  78. #define LIGHTGREY        2
  79. #define MEDIUMGREY       3
  80. #define DARKGREY         4
  81. #define GREEN            5
  82. #define BLUE             6
  83. #define ORANGE          86
  84. #define PURPLE          87
  85. #define RED             88
  86.  
  87. #define FREY             0
  88. #define LOKI             1
  89. #define NJORD            2
  90. #define ODIN             3
  91. #define THOR             4
  92. #define TYR              5
  93.  
  94. #define ABOUTXPIXEL    312
  95. #define ABOUTYPIXEL     76
  96.  
  97. #define MN_PROJECT       0
  98. #define MN_HELP          1
  99. #define IN_NEW           0
  100. #define IN_OPEN          1
  101. #define IN_SAVE          3
  102. #define IN_SAVEAS        4
  103. #define IN_QUIT          6
  104. #define IN_GAME_SUMMARY  0
  105. #define IN_ABOUT         2
  106.  
  107. #define TITLEBAR         "Saga 1.22"
  108. #define VERSION          "Saga 1.22 (5.11.2002)"
  109.  
  110. MODULE void place_monsters(void);
  111. MODULE void place_jarls(void);
  112. MODULE FLAG recruit(SLONG recruited, SLONG recruiterhero);
  113. MODULE void flee(SLONG routertype, SLONG router, SLONG routerhero, SLONG routedtype, SLONG routed, SLONG routedhero);
  114. MODULE void wound(SLONG woundertype, SLONG wounder, SLONG wounderhero, SLONG woundedtype, SLONG wounded, SLONG woundedhero);
  115. MODULE void kill(SLONG killertype, SLONG killer, SLONG killerhero, SLONG killedtype, SLONG killed, SLONG killedhero);
  116. MODULE void dobattle(SLONG defendtype, SLONG defender, SLONG attackhero);
  117. MODULE SLONG d6(void);
  118. MODULE SLONG getevent(SLONG mode, SLONG* countertype);
  119. MODULE void say(SLONG position);
  120. MODULE void newhero(SLONG whichhero, FLAG givesord);
  121. MODULE void showcountry(SLONG country);
  122. MODULE void phase1(void);
  123. MODULE void phase2(void);
  124. MODULE void phase3(void);
  125. MODULE void newgame(void);
  126. MODULE void gameloop(void);
  127. MODULE void clearkybd(void);
  128. MODULE void titlescreen(void);
  129. MODULE void gain(SLONG whichhero, SLONG glory, SLONG luck);
  130. MODULE void move(SLONG whichhero);
  131. MODULE void attack(SLONG whichhero);
  132. MODULE void helpabout(void);
  133. MODULE void resettime(void); 
  134. MODULE void anykey(void);
  135. MODULE SLONG getluck(SLONG whichhero);
  136. MODULE FLAG loadgame(FLAG aslwindow);
  137. MODULE void savegame(FLAG saveas);
  138. MODULE SLONG odin_tyr(LONG whichhero, FLAG attacking);
  139. MODULE void gods(SLONG whichhero);
  140. MODULE void pray(SLONG whichhero);
  141. MODULE void amiga_rout(SLONG routed, SLONG routedtype);
  142. MODULE void human_rout(SLONG routedtype, SLONG routed, SLONG routerhero);
  143. MODULE SLONG getmoves(SLONG countertype, SLONG whichcounter, FLAG freyfaxi);
  144. MODULE void faxi_disappear(void);
  145. MODULE void thor(SLONG whichhero);
  146. MODULE void cast(SLONG caster, SLONG whichspell);
  147. MODULE void darken(void);
  148. MODULE SLONG checkcountry(WORD mousex, WORD mousey);
  149. MODULE void infowindow(SLONG countertype, SLONG whichcounter);
  150. MODULE void getdefender(SLONG attackhero, SLONG here);
  151. MODULE FLAG needsord(SLONG countertype, SLONG counter);
  152. MODULE void brosung(SLONG countertype, SLONG whichcounter);
  153. MODULE void flash(SLONG country);
  154. MODULE FLAG assess(SLONG countertype, SLONG counter);
  155. MODULE void promote(SLONG whichhero, SLONG whichjarl);
  156. MODULE void withdraw(SLONG whichhero);
  157. MODULE FLAG asksord(SLONG countertype, SLONG counter, SLONG whichsord);
  158. MODULE void asktreasure(SLONG countertype, SLONG counter, SLONG whichtreasure);
  159. MODULE void pad(STRPTR thestring);
  160. MODULE void print_location(SLONG whichcountry, SLONG index);
  161. MODULE void print_sea(SLONG sea_value, SLONG index);
  162. MODULE void print_hagall(SLONG hagall_value, SLONG index);
  163. MODULE void print_paralyzed(SLONG paralyzed_value, SLONG index);
  164. MODULE void print_routed(SLONG routed_value, SLONG index);
  165. MODULE void amiga_attack(SLONG attackhero, SLONG defendtype, SLONG defender);
  166. MODULE FLAG ask_faxi(SLONG countertype, SLONG whichcounter);
  167. MODULE void saywho(SLONG countertype, SLONG counter, FLAG comma, FLAG lowercase);
  168. MODULE void callforaid(SLONG passedtype, SLONG passed);
  169. MODULE FLAG attackersleft(void);
  170. MODULE void dospell(SLONG spell, SLONG caster);
  171. MODULE void waitkey(void);
  172. MODULE void summarywindow(void);
  173. MODULE SLONG getattackers(SLONG whichhero, SLONG whichcountry);
  174.  
  175. MODULE struct
  176. {   UBYTE red, green, blue;
  177. } taxcolours[10 + 1] =
  178. {   {  0,  5,  0 }, // tax  0 (unused)
  179.     {  1,  6,  1 }, // tax  1 (unused)
  180.     {  2,  7,  2 }, // tax  2
  181.     {  3,  8,  3 }, // tax  3
  182.     {  4,  9,  4 }, // tax  4
  183.     {  5, 10,  5 }, // tax  5
  184.     {  6, 11,  6 }, // tax  6
  185.     {  7, 12,  7 }, // tax  7
  186.     {  8, 13,  8 }, // tax  8
  187.     {  9, 14,  9 }, // tax  9
  188.     { 10, 15, 10 }  // tax 10
  189. };
  190.  
  191. #define ABOUTLINES     3
  192. struct
  193. {   WORD x, y;
  194.     TEXT text[80 + 1];
  195. } about[ABOUTLINES + 1] =
  196. {   {72, 27},
  197.     {72, 35},
  198.     {72, 51},
  199.     {72, 59}
  200. };
  201.  
  202. #define MENUENTRIES 12
  203. struct NewMenu NewMenu[MENUENTRIES + 1] =
  204. {   { NM_TITLE, "",           0 , 0, 0, 0}, //  0
  205.     {  NM_ITEM, "",          "" , 0, 0, 0}, //  1
  206.     {  NM_ITEM, "",          "" , 0, 0, 0}, //  2
  207.     {  NM_ITEM, NM_BARLABEL,  0 , 0, 0, 0}, //  3
  208.     {  NM_ITEM, "",          "" , 0, 0, 0}, //  4
  209.     {  NM_ITEM, "",          "" , 0, 0, 0}, //  5
  210.     {  NM_ITEM, NM_BARLABEL,  0 , 0, 0, 0}, //  6
  211.     {  NM_ITEM, "",          "" , 0, 0, 0}, //  7
  212.     { NM_TITLE, "",           0 , 0, 0, 0}, //  8
  213.     {  NM_ITEM, "",          "" , 0, 0, 0}, //  9
  214.     {  NM_ITEM, NM_BARLABEL,  0 , 0, 0, 0}, // 10
  215.     {  NM_ITEM, "",          "?", 0, 0, 0}, // 11
  216.     {   NM_END, NULL,         0 , 0, 0, 0}  // 12
  217. };
  218.  
  219. // These are better to not be allocated on the stack
  220. MODULE ULONG table1[] = {(8L << 16) + 0,
  221.     0x00000000, 0x00000000, 0x00000000, // 0 (BLACK)
  222.     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, // 1 (WHITE)
  223.     0xCCCCCCCC, 0xCCCCCCCC, 0xCCCCCCCC, // 2 (LIGHTGREY)
  224.     0x99999999, 0x99999999, 0x99999999, // 3 (MEDIUMGREY)
  225.     0x66666666, 0x66666666, 0x66666666, // 4 (DARKGREY)
  226.     0x66666666, 0xFFFFFFFF, 0x66666666, // 5 (GREEN)
  227.     0x88888888, 0x88888888, 0xFFFFFFFF, // 6 (BLUE)
  228.     0x00000000, 0x00000000, 0x00000000, // 7
  229.     0};
  230. MODULE ULONG table2[] = {(54L << 16) + 74,
  231.     0x99999999, 0x99999999, 0xFFFFFFFF, // 74
  232.     0x99999999, 0xFFFFFFFF, 0x99999999, // 75
  233.     0xFFFFFFFF, 0xCCCCCCCC, 0x99999999, // 76
  234.     0xFFFFFFFF, 0x99999999, 0xFFFFFFFF, // 77
  235.     0xFFFFFFFF, 0xFFFFFFFF, 0x99999999, // 78
  236.     0x00000000, 0x00000000, 0x00000000, // 79
  237.     0x00000000, 0x00000000, 0x00000000, // 80
  238.     0x00000000, 0x00000000, 0x99999999, // 81
  239.     0x00000000, 0x00000000, 0x00000000, // 82
  240.     0x00000000, 0x00000000, 0x99999999, // 83
  241.     0x00000000, 0x00000000, 0x00000000, // 84
  242.     0x00000000, 0x00000000, 0x99999999, // 85
  243.     0xFFFFFFFF, 0x99999999, 0x88888888, // 86 (ORANGE)
  244.     0xFFFFFFFF, 0x88888888, 0xFFFFFFFF, // 87 (PURPLE)
  245.     0xFFFFFFFF, 0x55555555, 0x55555555, // 88 (RED)
  246.     0x00000000, 0x00000000, 0x00000000, // 89
  247.     0x00000000, 0x00000000, 0x00000000, // 90
  248.     0x00000000, 0x00000000, 0x00000000, // 91
  249.     0x00000000, 0x00000000, 0x00000000, // 92
  250.     0x00000000, 0x00000000, 0xFFFFFFFF, // 93
  251.     0x10101010, 0x14141414, 0xFFFFFFFF, // 94
  252.     0x1F1F1F1F, 0x23232323, 0xFFFFFFFF, // 95
  253.     0x2E2E2E2E, 0x32323232, 0xFFFFFFFF, // 96
  254.     0x3D3D3D3D, 0x41414141, 0xFFFFFFFF, // 97
  255.     0x4C4C4C4C, 0x4F4F4F4F, 0xFFFFFFFF, // 98
  256.     0x5B5B5B5B, 0x5E5E5E5E, 0xFFFFFFFF, // 99
  257.     0x6A6A6A6A, 0x6D6D6D6D, 0xFFFFFFFF, // 100
  258.     0x79797979, 0x7C7C7C7C, 0xFFFFFFFF, // 101
  259.     0x87878787, 0x89898989, 0xFFFFFFFF, // 102
  260.     0x96969696, 0x98989898, 0xFFFFFFFF, // 103
  261.     0xA5A5A5A5, 0xA7A7A7A7, 0xFFFFFFFF, // 104
  262.     0xB4B4B4B4, 0xB6B6B6B6, 0xFFFFFFFF, // 105
  263.     0xC3C3C3C3, 0xC4C4C4C4, 0xFFFFFFFF, // 106
  264.     0xD2D2D2D2, 0xD3D3D3D3, 0xFFFFFFFF, // 107
  265.     0xE1E1E1E1, 0xE2E2E2E2, 0xFFFFFFFF, // 108
  266.     0xF0F0F0F0, 0xF1F1F1F1, 0xFFFFFFFF, // 109
  267.     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, // 110
  268.     0x00000000, 0x00000000, 0xFFFFFFFF, // 111
  269.     0x00000000, 0x88888888, 0xFFFFFFFF, // 112
  270.     0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, // 113
  271.     0x00000000, 0xFFFFFFFF, 0x88888888, // 114
  272.     0x00000000, 0xFFFFFFFF, 0x00000000, // 115
  273.     0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, // 116
  274.     0xFFFFFFFF, 0xDDDDDDDD, 0x00000000, // 117
  275.     0xFFFFFFFF, 0xC5C5C5C5, 0x00000000, // 118
  276.     0xFFFFFFFF, 0xA7A7A7A7, 0x00000000, // 119
  277.     0xFFFFFFFF, 0x89898989, 0x00000000, // 120
  278.     0xFFFFFFFF, 0x72727272, 0x00000000, // 121
  279.     0xFFFFFFFF, 0x54545454, 0x00000000, // 122
  280.     0xFFFFFFFF, 0x36363636, 0x00000000, // 123
  281.     0xFFFFFFFF, 0x1E1E1E1E, 0x00000000, // 124
  282.     0xFFFFFFFF, 0x00000000, 0x00000000, // 125
  283.     0x00000000, 0x00000000, 0x00000000, // 126
  284.     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, // 127
  285.     0};
  286.  
  287. MODULE struct NewGadget SpeedGadget =
  288. {   300, 312,
  289.     128, 13,
  290.     "",
  291.     NULL,
  292.     NULL,
  293.     NULL,
  294.     NULL,
  295.     NULL
  296. }, CycleGadget[HEROES + 1] = {
  297. {   300, 200,
  298.     128, 13,
  299.     NULL,
  300.     NULL,
  301.     NULL,
  302.     NULL,
  303.     NULL,
  304.     NULL
  305. },
  306. {   300, 216,
  307.     128, 13,
  308.     NULL,
  309.     NULL,
  310.     NULL,
  311.     NULL,
  312.     NULL,
  313.     NULL
  314. },
  315. {   300, 232,
  316.     128, 13,
  317.     NULL,
  318.     NULL,
  319.     NULL,
  320.     NULL,
  321.     NULL,
  322.     NULL
  323. },
  324. {   300, 248,
  325.     128, 13,
  326.     NULL,
  327.     NULL,
  328.     NULL,
  329.     NULL,
  330.     NULL,
  331.     NULL
  332. },
  333. {   300, 264,
  334.     128, 13,
  335.     NULL,
  336.     NULL,
  337.     NULL,
  338.     NULL,
  339.     NULL,
  340.     NULL
  341. },
  342. {   300, 280,
  343.     128, 13,
  344.     NULL,
  345.     NULL,
  346.     NULL,
  347.     NULL,
  348.     NULL,
  349.     NULL
  350. }
  351. };
  352.  
  353. #define HERO_STRENGTH 5
  354. #define HERO_MOVES    4
  355.  
  356. #define RUNES         5
  357.  
  358. SLONG cycleheropos[HEROES + 1] =
  359. {   2,
  360.     3,
  361.     5,
  362.     3,
  363.     0,
  364.     3
  365. };
  366.  
  367. MODULE struct
  368. {   UBYTE red, green, blue;
  369. } herocolour[HEROES + 1] =
  370. { { 15,  12,   6}, // orange
  371.   { 15,   6,   6}, // red
  372.   { 15,  15,   3}, // yellow
  373.   {  6,  15,  15}, // cyan
  374.   { 10,  10,  15}, // light blue
  375.   { 15,   6,  15}  // purple
  376. };
  377. STRPTR trueheroname[HEROES + 1] =
  378. {   "Beowulf",
  379.     "Brunhild",
  380.     "Egil",
  381.     "Ragnar",
  382.     "Siegfried",
  383.     "Starkad"
  384. }, cycleheroname[HEROES + 1] =
  385. {   "  Beowulf:",
  386.     " Brunhild:",
  387.     "     Egil:",
  388.     "   Ragnar:",
  389.     "Siegfried:",
  390.     "  Starkad:"
  391. }, runename[RUNES + 1] =
  392. {   "Amsir",
  393.     "Eon",
  394.     "Geofu",
  395.     "Ing",
  396.     "Ogal",
  397.     "Sygil",
  398. };
  399.  
  400. AGLOBAL struct JarlStruct jarl[JARLS + 1] =
  401. { { 2, 3, "Amleth"    },
  402.   { 3, 3, "Bjarki"    },
  403.   { 3, 3, "Erik"      },
  404.   { 2, 2, "Eyjolf"    },
  405.   { 2, 2, "Gretter"   },
  406.   { 2, 2, "Hagen"     },
  407.   { 2, 3, "Harald"    },
  408.   { 2, 3, "Helgi"     },
  409.   { 2, 2, "Hengist"   },
  410.   { 2, 2, "Horsi"     },
  411.   { 4, 2, "Hrolfwulf" },
  412.   { 4, 2, "Ivar"      },
  413.   { 4, 3, "Kari"      },
  414.   { 2, 3, "Skallagrim"},
  415.   { 3, 3, "Thorolf"   },
  416.   { 2, 3, "Thorvald"  },
  417.   { 3, 3, "Welland"   },
  418.   { 3, 3, "Wiglar"    }
  419. };
  420.  
  421. #define BEOWULF         0
  422. #define BRUNHILD        1
  423. #define EGIL            2
  424. #define RAGNAR          3
  425. #define SIEGFRIED       4
  426. #define STARKAD         5
  427. AGLOBAL struct HeroStruct hero[HEROES + 1];
  428.  
  429. #define BALMUNG         0
  430. #define DRAGVENDILL     1
  431. #define GRAM            2
  432. #define HRUNTING        3
  433. #define LOVI            4
  434. #define TYRFING         5
  435. struct SordStruct sord[SORDS + 1] =
  436. { { "Balmung (+1)"    },
  437.   { "Dragvendill (+2)"},
  438.   { "Gram (+2)"       },
  439.   { "Hrunting (+1)"   },
  440.   { "Lovi (+1)"       },
  441.   { "Tyrfing (+2)"    }
  442. };
  443.  
  444. #define BROSUNGNECKLACE 0
  445. #define FREYFAXI        1
  446. #define MAGICSHIRT      2
  447. #define MAILCOAT        3
  448. struct TreasureStruct treasure[TREASURES + 1] =
  449. { {""         },
  450.   {"Frey Faxi"},
  451.   {""         },
  452.   {""         }
  453. };
  454.  
  455. #define DRAGON 0
  456. #define DROW   1
  457. #define GIANT  2
  458. #define GHOST  3
  459. #define TROLL  4
  460. #define WITCH  5
  461. AGLOBAL struct MonsterStruct monster[MONSTERS + 1] =
  462. { { DRAGON, 10, 1, "Aludreng" },
  463.   { DRAGON, 11, 2, "Fafnir"   },
  464.   { DRAGON, 10, 2, "Glerion"  },
  465.   { DRAGON, 10, 2, "Hallbjorn"},
  466.   { DRAGON,  9, 3, "Istvan"   },
  467.   { DRAGON, 11, 2, "Stigandi" },
  468.   { DROW,    2, 2, "Atli"     },
  469.   { DROW,    3, 1, "Gizur"    },
  470.   { DROW,    3, 1, "Hallgerd" },
  471.   { GHOST,   4, 2, "Gizar"    },
  472.   { GHOST,   4, 1, "Glam"     },
  473.   { GHOST,   4, 0, "Gunnar"   },
  474.   { GHOST,   4, 0, "Hrap"     },
  475.   { GHOST,   4, 1, "Mord"     },
  476.   { GHOST,   4, 1, "Trogrier" },
  477.   { GIANT,   7, 0, "Angantyr" },
  478.   { GIANT,   6, 1, "Hall"     },
  479.   { GIANT,   8, 1, "Storvick" },
  480.   { TROLL,   6, 2, "Grendall" },
  481.   { TROLL,   5, 2, "Hallbjorn"},
  482.   { TROLL,   5, 1, "Hauk"     },
  483.   { TROLL,   6, 1, "Hogshead" },
  484.   { TROLL,   5, 3, "Onund"    },
  485.   { TROLL,   5, 2, "Svinafell"},
  486.   { WITCH,   3, 4, "Gerdrak"  },
  487.   { WITCH,   3, 5, "Grunhild" },
  488.   { WITCH,   4, 4, "Hedin"    }
  489. };
  490.  
  491. /* These are the statistical distribution of the taxation factors:
  492.     4x  2 tax
  493.    10x  3 tax
  494.     3x  4 tax
  495.     3x  5 tax
  496.     6x  6 tax
  497.     4x  7 tax
  498.     1x  8 tax
  499.     2x  9 tax
  500.     3x 10 tax */
  501.  
  502. #define LAND      0
  503. #define SEA       1
  504. #define ISLE      2
  505. #define PENINSULA 3
  506. AGLOBAL struct WorldStruct world[36 + 30] =
  507. {   {590,  39,  3, LAND,      "Finmark"  ,       1, -1, -1, -1, -1, -1, -1, -1}, // 1:1 ( 0) (inland)
  508.     {584, 104,  3, LAND,      "Trondheim",       0,  2,  3, 60, -1, -1, -1, -1}, // 1:2 ( 1)
  509.     {489, 102,  6, LAND,      "Mordaland",       1,  3,  4, 55, 59, 60, -1, -1}, // 1:3 ( 2)
  510.     {573, 173,  2, LAND,      "Upland",          1,  2,  4,  5,  6, -1, -1, -1}, // 1:4 ( 3) (inland)
  511.     {451, 176,  5, LAND,      "Agdar",           2,  3,  5, 48, 49, 54, 55, -1}, // 1:5 ( 4)
  512.     {514, 201,  3, LAND,      "Romeirt",         3,  4,  6,  7, 47, 48, -1, -1}, // 1:6 ( 5)
  513.     {569, 233,  7, LAND,      "Jamtland",        3,  5,  7,  8, 65, -1, -1, -1}, // 2:1 ( 6)
  514.     {512, 262,  6, LAND,      "Vester Gotland",  5,  6,  8,  9, 47, -1, -1, -1}, // 2:2 ( 7)
  515.     {549, 305,  7, LAND,      "Oster Gotland",   6,  7,  9, 63, 65, -1, -1, -1}, // 2:3 ( 8)
  516.     {502, 323,  4, LAND,      "Suder Gotland",   7,  8, 11, 47, 63, -1, -1, -1}, // 2:4 ( 9)
  517.     {420, 287,  6, LAND,      "Juteland",       11, 14, 46, 47, 48, 49, -1, -1}, // 2:5 (10)
  518.     {441, 344,  3, ISLE,      "Scandia",         9, 10, 12, 13, 14, 47, 63, -1}, // 2:6 (11)
  519.     {522, 442,  4, LAND,      "Pomerania",      11, 13, 63, 64, -1, -1, -1, -1}, // 3:1 (12)
  520.     {393, 421,  6, LAND,      "Saxony",         11, 12, 14, 15, 16, 46, -1, -1}, // 3:2 (13)
  521.     {392, 372,  7, LAND,      "Anglia",         10, 11, 13, 46, -1, -1, -1, -1}, // 3:3 (14)
  522.     {305, 383,  7, LAND,      "Fenland",        13, 16, 17, 44, 45, 46, -1, -1}, // 3:4 (15)
  523.     {305, 434, 10, LAND,      "Rhineland",      13, 15, 17, -1, -1, -1, -1, -1}, // 3:5 (16) (inland)
  524.     {242, 428,  9, LAND,      "Frisia",         15, 16, 18, 44, -1, -1, -1, -1}, // 3:6 (17)
  525.     {175, 438,  3, LAND,      "Frankland",      17, 19, 43, 44, -1, -1, -1, -1}, // 4:1 (18)
  526.     { 97, 439, 10, LAND,      "Armorica",       18, 42, 43, -1, -1, -1, -1, -1}, // 4:2 (19)
  527.     { 75, 318,  2, LAND,      "Cornwall",       21, 42, 43, -1, -1, -1, -1, -1}, // 4:3 (20)
  528.     {109, 333, 10, LAND,      "Wessex",         20, 22, 23, 24, 25, 42, 43, -1}, // 4:4 (21)
  529.     {153, 354,  9, LAND,      "Sussex",         21, 23, 24, 43, 44, -1, -1, -1}, // 4:5 (22)
  530.     {190, 329,  6, LAND,      "East Anglia",    22, 24, 44, 45, -1, -1, -1, -1}, // 4:6 (23)
  531.     {148, 313,  3, LAND,      "Mercia",         21, 22, 23, 25, 26, 27, 45, 51}, // 5:1 (24)
  532.     {108, 287,  3, LAND,      "Daffyd",         21, 24, 26, 41, 42, -1, -1, -1}, // 5:2 (25)
  533.     {145, 268,  2, LAND,      "Gwynedd",        24, 25, 27, 41, -1, -1, -1, -1}, // 5:3 (26)
  534.     {186, 217,  8, LAND,      "Northumberland", 24, 26, 28, 41, 51, 52, -1, -1}, // 5:4 (27)
  535.     {178, 157,  3, LAND,      "Dalriada",       27, 29, 30, 40, 41, 52, -1, -1}, // 5:5 (28)
  536.     {222, 130,  5, LAND,      "Caledonia",      28, 30, 52, 57, -1, -1, -1, -1}, // 5:6 (29)
  537.     {230,  85,  2, PENINSULA, "Pictland",       28, 29, 31, 40, 57, 58, 61, 62}, // 6:1 (30)
  538.     {167,  66,  3, ISLE,      "Hebrides",       30, 36, 39, 40, 62, -1, -1, -1}, // 6:2 (31)
  539.     { 62,  40,  3, LAND,      "Thule",          36, 37, -1, -1, -1, -1, -1, -1}, // 6:3 (32)
  540.     { 54, 162,  5, LAND,      "Connacht",       34, 35, 38, 39, -1, -1, -1, -1}, // 6:4 (33)
  541.     {109, 162,  4, LAND,      "Ulster",         33, 35, 39, 40, 41, -1, -1, -1}, // 6:5 (34)
  542.     { 60, 203,  6, LAND,      "Leinster",       33, 34, 41, -1, -1, -1, -1, -1}, // 6:6 (35)
  543.     {134,  32,  0, SEA,       "",               31, 32, 37, 39, -1, -1, -1, -1}, //     (36)
  544.     { 52,  94,  0, SEA,       "",               32, 36, 38, 39, -1, -1, -1, -1}, //     (37)
  545.     { 53, 130,  0, SEA,       "",               33, 37, 39, -1, -1, -1, -1, -1}, //     (38)
  546.     { 82, 118,  0, SEA,       "",               31, 33, 34, 36, 37, 38, 40, -1}, //     (39)
  547.     {137, 165,  0, SEA,       "",               28, 30, 31, 34, 39, 41, -1, -1}, //     (40)
  548.     {116, 225,  0, SEA,       "",               25, 26, 27, 28, 34, 35, 40, 42}, //     (41)
  549.     { 57, 292,  0, SEA,       "",               19, 20, 21, 25, 41, 43, -1, -1}, //     (42)
  550.     {127, 389,  0, SEA,       "",               18, 19, 20, 21, 22, 42, 44, -1}, //     (43)
  551.     {217, 370,  0, SEA,       "",               15, 17, 18, 22, 23, 43, 45, -1}, //     (44)
  552.     {261, 328,  0, SEA,       "",               15, 23, 24, 44, 46, 50, 51, -1}, //     (45)
  553.     {343, 334,  0, SEA,       "",               10, 13, 14, 15, 45, 49, 50, -1}, //     (46)
  554.     {467, 282,  0, SEA,       "Kategatt",        5,  7,  9, 10, 11, 48, -1, -1}, //     (47)
  555.     {445, 229,  0, SEA,       "Skagerrak",       4,  5, 10, 47, 49, -1, -1, -1}, //     (48)
  556.     {376, 270,  0, SEA,       "",                4, 10, 48, 46, 50, 54, -1, -1}, //     (49)
  557.     {311, 268,  0, SEA,       "",               45, 46, 49, 51, 53, 54, -1, -1}, //     (50) (deep waters)
  558.     {240, 258,  0, SEA,       "",               24, 27, 45, 50, 52, 53, -1, -1}, //     (51)
  559.     {248, 193,  0, SEA,       "",               27, 28, 29, 51, 53, 56, 57, -1}, //     (52)
  560.     {324, 196,  0, SEA,       "",               50, 51, 52, 54, 55, 56, -1, -1}, //     (53) (deep waters)
  561.     {379, 186,  0, SEA,       "",                4, 49, 50, 53, 55, -1, -1, -1}, //     (54)
  562.     {386, 124,  0, SEA,       "",                2,  4, 53, 54, 56, 58, 59, -1}, //     (55)
  563.     {318, 134,  0, SEA,       "",               52, 53, 55, 57, 58, -1, -1, -1}, //     (56) (deep waters)
  564.     {267, 133,  0, SEA,       "",               29, 30, 52, 56, 58, -1, -1, -1}, //     (57)
  565.     {338,  90,  0, SEA,       "",               30, 55, 56, 57, 59, 60, 61, -1}, //     (58)
  566.     {427,  73,  0, SEA,       "",                2, 55, 58, 60, -1, -1, -1, -1}, //     (59)
  567.     {456,  27,  0, SEA,       "",                1,  2, 58, 59, 61, -1, -1, -1}, //     (60)
  568.     {341,  47,  0, SEA,       "",               30, 58, 60, 62, -1, -1, -1, -1}, //     (61)
  569.     {257,  44,  0, SEA,       "",               30, 31, 61, -1, -1, -1, -1, -1}, //     (62)
  570.     {509, 385,  0, SEA,       "",                8,  9, 11, 12, 64, 65, -1, -1}, //     (63)
  571.     {587, 404,  0, SEA,       "",               12, 63, 65, -1, -1, -1, -1, -1}, //     (64)
  572.     {587, 345,  0, SEA,       "",                6,  8, 63, 64, -1, -1, -1, -1}  //     (65)
  573. };
  574.  
  575. #define NONE  0
  576. #define HUMAN 1
  577. #define AMIGA 2
  578.  
  579. #define MAXLINES 45
  580. #define LEFTSIDE  0
  581. #define RIGHTSIDE 1
  582.  
  583. IMPORT  struct ExecBase*      SysBase;
  584. IMPORT  struct Custom         custom;
  585.  
  586. AGLOBAL struct GfxBase*       GfxBase       = NULL;
  587. AGLOBAL struct GadToolsBase*  GadToolsBase  = NULL;
  588. AGLOBAL struct IntuitionBase* IntuitionBase = NULL;
  589. AGLOBAL struct LocaleBase*    LocaleBase    = NULL;
  590. AGLOBAL struct Library*       TimerBase     = NULL;
  591. AGLOBAL struct ASLBase*       ASLBase       = NULL;
  592.  
  593. AGLOBAL struct Window        *MainWindowPtr = NULL,
  594.                              *HelpWindowPtr = NULL,
  595.                              *InfoWindowPtr = NULL;
  596. AGLOBAL UWORD                 DisplayDepth  = DEPTH;
  597. AGLOBAL struct Screen*        ScreenPtr     = NULL;
  598.  
  599. MODULE  WORD                  speed         = 4;
  600. MODULE  UBYTE                 IOBuffer[600];
  601. MODULE  ULONG                 DisplayID     = HIRES_KEY | PAL_MONITOR_ID | LACE,
  602.                               DisplayWidth  = SCREENXPIXEL,
  603.                               DisplayHeight = SCREENYPIXEL;
  604. MODULE  struct RDArgs*        ArgsPtr       = NULL;
  605. MODULE  struct FileRequester* ASLRqPtr      = NULL;
  606. MODULE  struct Process*       ProcessPtr    = NULL;
  607. MODULE  struct Menu*          MenuPtr       = NULL;
  608. MODULE  struct VisualInfo*    VisualInfoPtr = NULL;
  609. MODULE  APTR                  OldWindowPtr  = NULL;
  610. MODULE  FLAG                  gameover,
  611.                               loaded,
  612.                               cliload                    = FALSE;
  613. MODULE  SLONG                 faxirides,
  614.                               tickwait                   = 7, // measured in intuiticks (10ths of a second)
  615.                               turn,
  616.                               order[HEROES + 1];
  617. MODULE  TEXT                  abouttitle[80 + 1],
  618.                               saystring[256 + 1],
  619.                               numberstring[13 + 1],
  620.                               titlestring[80 + 1],
  621.                               pathname[256 + 1],
  622.                               line[2][MAXLINES + 1][80 + 1];
  623. MODULE  struct Gadget        *SpeedGadgetPtr             = NULL,
  624.                              *CycleGadgetPtr[HEROES + 1] = {NULL, NULL, NULL, NULL, NULL, NULL},
  625.                              *GListPtr                   = NULL,
  626.                              *PrevGadgetPtr              = NULL;
  627. MODULE  struct LocaleInfo     li;
  628. MODULE  STRPTR                CycleOptions[4],
  629.                               monstertypes[6],
  630.                               runedesc[RUNES + 1];
  631.  
  632. #define ONEKEY_YES           0
  633. #define ONEKEY_NO            1
  634. #define ONEKEY_WITHDRAW      2
  635. #define ONEKEY_RESTART       3
  636. #define ONEKEY_TRANSFER      4
  637. #define ONEKEY_GLORY         5
  638. #define ONEKEY_LUCK          6
  639. #define ONEKEYS              ONEKEY_LUCK
  640.  
  641. TEXT onekey[ONEKEYS + 1] =
  642. {   'Y', 'N', 'W', 'R', 'T', 'G', 'L'
  643. };
  644.  
  645. MODULE void place_monsters(void)
  646. {   /* .taken = FALSE: the monster is in the "pile of monsters" (spare).
  647.                 TRUE : the monster is either on the board or dead. */
  648.  
  649.     SLONG whichhero, whichmonster, whichtreasure;
  650.     FLAG  available, ok;
  651.  
  652.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  653.     {   if (hero[whichhero].alive)
  654.         {   available = FALSE;
  655.             for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  656.             {   if (!monster[whichmonster].taken)
  657.                 {   available = TRUE;
  658.                     break;
  659.             }   }
  660.             if (available)
  661.             {   do
  662.                 {   whichmonster = rand() % (MONSTERS + 1);
  663.                 } while (monster[whichmonster].taken);
  664.                 monster[whichmonster].taken    =
  665.                 monster[whichmonster].alive    = TRUE;
  666.                 monster[whichmonster].where    = rand() % 36;
  667.                 monster[whichmonster].sea      = NORMAL;
  668.                 monster[whichmonster].hagall   = FALSE;
  669.  
  670.                 if (monster[whichmonster].species == DRAGON)
  671.                 {   ok = FALSE;
  672.                     for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  673.                     {   if (!treasure[whichtreasure].taken)
  674.                         {   ok = TRUE; // at least one treasure is available
  675.                             break; // for speed
  676.                     }   }
  677.                     if (ok)
  678.                     {   do
  679.                         {   whichtreasure = rand() % (TREASURES + 1);
  680.                         } while (treasure[whichtreasure].taken);
  681.                         treasure[whichtreasure].taken         = TRUE;
  682.                         treasure[whichtreasure].possessortype = MONSTER;
  683.                         treasure[whichtreasure].possessor     = whichmonster;
  684.                         treasure[whichtreasure].where         = -1;
  685.  
  686.                         monster[whichmonster].wealth = 0;
  687.                     } else
  688.                     {   monster[whichmonster].wealth = 20;
  689.                 }   }
  690.                 else
  691.                 {   monster[whichmonster].wealth = 0;
  692.                 }
  693.                 // we don't unslot newborn counters
  694.                 move_monster(whichmonster, FALSE);
  695. }   }   }   }
  696.  
  697. MODULE void place_jarls(void)
  698. {   FLAG  available;
  699.     SLONG whichhero, whichjarl;
  700.  
  701.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  702.     {   if (hero[whichhero].alive)
  703.         {   available = FALSE;
  704.             for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  705.             {   if (!jarl[whichjarl].taken)
  706.                 {   available = TRUE;
  707.                     break;
  708.             }   }
  709.             if (available)
  710.             {   do
  711.                 {   whichjarl = rand() % (JARLS + 1);
  712.                 } while (jarl[whichjarl].taken);
  713.                 jarl[whichjarl].taken     =
  714.                 jarl[whichjarl].alive     = TRUE;
  715.                 jarl[whichjarl].wealth    = 0;
  716.                 jarl[whichjarl].where     =
  717.                 jarl[whichjarl].homewhere = rand() % 36;
  718.                 jarl[whichjarl].hero      = -1;
  719.                 jarl[whichjarl].sea       = NORMAL;
  720.                 jarl[whichjarl].hagall    =
  721.                 jarl[whichjarl].loseturn  = FALSE;
  722.                 hidejarl(whichjarl, FALSE);
  723.                 // we don't unslot newborn counters
  724.                 move_jarl(whichjarl, FALSE);
  725. }   }   }   }
  726.  
  727. int main(int argc, char** argv)
  728. {   struct TextAttr             Topaz8 =
  729.     {   (STRPTR) "topaz.font", 8, FS_NORMAL, FPF_ROMFONT | FPF_DESIGNED
  730.     };
  731.     struct DateTime             DateTime;
  732.     struct ScreenModeRequester* smr;
  733.     BPTR                        FileHandle /* = NULL */ ;
  734.     FLAG                        ok;
  735.     TEXT                        datestring[LEN_DATSTRING],
  736.                                 weekdaystring[LEN_DATSTRING],
  737.                                 tempstring[1 + 1],
  738.                                 smrstring[80 + 1],
  739.                                 supergels[2];
  740.     SLONG                       whichcountry, whichhero,
  741.                                 args[7] = {0L, 0L, 0L, 0L, 0L, 0L, 0L};
  742.     UWORD                       Pens[13] =
  743.     {   BLACK,     /* DETAILPEN            text in title bar */
  744.         WHITE,     /* BLOCKPEN             fill title bar */
  745.         WHITE,     /* TEXTPEN              regular text on BACKGROUNDPEN (was BLACK) */
  746.         LIGHTGREY, /* SHINEPEN             bright edge */
  747.         DARKGREY,  /* SHADOWPEN            dark edge */
  748.         BLUE,      /* FILLPEN              filling active window borders
  749.                                            and selected gadgets */
  750.         BLACK,     /* FILLTEXTPEN          text rendered over FILLPEN */
  751.         BLACK,     /* BACKGROUNDPEN        background colour (was BLUE) */
  752.         ORANGE,    /* HIGHLIGHTTEXTPEN     highlighted text on BACKGROUNDPEN
  753.                                            and used against BLOCKPEN in ASL
  754.                                            save requesters */
  755.         BLACK,     /* BARDETAILPEN         text/detail in screen-bar/menus */
  756.         WHITE,     /* BARBLOCKPEN          screen-bar/menus fill */
  757.         BLACK,     /* BARTRIMPEN           trim under screen-bar */
  758.         (UWORD) ~0 /* and used against BLOCKPEN in ASL save requesters */
  759.     };
  760.  
  761. /* Colour allocations are as follows:
  762.     colours 0-6 are used by the game itself.
  763.     colour 7 is the black of the map.
  764.     colours 8-43 are map land colours, except that
  765.     colours 17-19 are mouse pointer colours.
  766.     colours 44-73 are map sea colours.
  767.     colour 74 is hero counter colour (blue).
  768.     colour 75 is jarl counter colour (green).
  769.     colour 76 is monster counter colour (orange).
  770.     colour 77 is treasure counter colour (purple).
  771.     colour 78 is sword counter colour (yellow).
  772.     colour 79 is the black of the counters.
  773.     colour 80 is Scandian coastline.
  774.     colour 81 is Scandian sea.
  775.     colour 82 is Pictish coastline.
  776.     colour 83 is Pictish sea.
  777.     colour 84 is Hebridean coastline.
  778.     colour 85 is Hebridean sea.
  779.     colours 86-88 are used by the game itself.
  780.     colour 89 is Suder Gotland land (replacement for colour 17).
  781.     colour 90 is Juteland land (replacement for colour 18).
  782.     colour 91 is Scandian land (replacement for colour 19).
  783.     colours 92-110 are used for the Saga logo.
  784.     colours 111-125 (and others) are used for the Amigan Software logo.
  785.     colour 126 is selected menu text.
  786.     colour 127 is selected menu background.
  787.  
  788.     Start of program.
  789.  
  790.     version embedding into executable */
  791.     if (0) /* that is, never */
  792.     {   Printf("%s\n", VERSION);
  793.     }
  794.  
  795.     // before the first possible point of failure
  796.     init_counters();
  797.     for (whichcountry = 0; whichcountry <= 65; whichcountry++)
  798.     {   world[whichcountry].hero = -1;
  799.     }
  800.     pathname[0] = 0;
  801.  
  802.     if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39L)))
  803.     {   strcpy(saystring, "Saga: Can't open intuition.library V39+!)\n");
  804.         Write(Output(), saystring, strlen(saystring));
  805.         cleanexit(EXIT_FAILURE);
  806.     }
  807.  
  808.     ProcessPtr = (struct Process *) FindTask(NULL);
  809.  
  810.     if (SysBase->LibNode.lib_Version < 36L)
  811.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open exec.library V36+!\0", 24);
  812.     cleanexit(EXIT_FAILURE);
  813.     }
  814.  
  815.     // From this point onwards, we can be sure we have Kickstart 2.0+...
  816.  
  817.     if (GetVar("cybergfx/supergels", supergels, 2, NULL) == 1)
  818.     {   if (supergels[0] == '1')
  819.         {   Printf("Saga: ENV:cybergfx/supergels must be cleared to 0 before playing!\n");
  820.             cleanexit(EXIT_FAILURE);
  821.     }   }
  822.  
  823.     /* NOTES FOR TRANSLATORS:
  824.       MSG_CHAR_FOO messages are single-character strings which are the
  825.     first letter of the relevant word. MSG_UNCHAR_FOO messages are the
  826.     rest of the word. Eg. in English, MSG_CHAR_GLORY is "G" and
  827.     MSG_UNCHAR_GLORY is "lory". They must each be different among their
  828.     'set' (yes/no, glory/luck, restart/transfer/withdraw). */
  829.  
  830.     li.li_Catalog = NULL;
  831.     if (LocaleBase = OpenLibrary("locale.library", 38))
  832.     {   li.li_LocaleBase   = LocaleBase;
  833.         li.li_Catalog      = OpenCatalog(NULL, "Saga.catalog", TAG_DONE);
  834.     }
  835.     strcpy(tempstring, GetCatalogStr(li.li_Catalog, MSG_CHAR_YES,      "Y"));
  836.     onekey[ONEKEY_YES]      = tempstring[0];
  837.     strcpy(tempstring, GetCatalogStr(li.li_Catalog, MSG_CHAR_NO,       "N"));
  838.     onekey[ONEKEY_NO]       = tempstring[0];
  839.     strcpy(tempstring, GetCatalogStr(li.li_Catalog, MSG_CHAR_WITHDRAW, "W"));
  840.     onekey[ONEKEY_WITHDRAW] = tempstring[0];
  841.     strcpy(tempstring, GetCatalogStr(li.li_Catalog, MSG_CHAR_RESTART,  "R"));
  842.     onekey[ONEKEY_RESTART]  = tempstring[0];
  843.     strcpy(tempstring, GetCatalogStr(li.li_Catalog, MSG_CHAR_TRANSFER, "T"));
  844.     onekey[ONEKEY_TRANSFER] = tempstring[0];
  845.     strcpy(tempstring, GetCatalogStr(li.li_Catalog, MSG_CHAR_GLORY,    "G"));
  846.     onekey[ONEKEY_GLORY]    = tempstring[0];
  847.     strcpy(tempstring, GetCatalogStr(li.li_Catalog, MSG_CHAR_LUCK,     "L"));
  848.     onekey[ONEKEY_LUCK]     = tempstring[0];
  849.     CycleOptions[0] = GetCatalogStr(li.li_Catalog, MSG_GADGET_NONE, "None");
  850.     CycleOptions[1] = GetCatalogStr(li.li_Catalog, MSG_HUMAN, "Human");
  851.     CycleOptions[2] = "Amiga";
  852.     CycleOptions[3] = NULL;
  853.     strcpy(abouttitle, GetCatalogStr(li.li_Catalog, MSG_ABOUT, "About"));
  854.     strcat(abouttitle, " Saga");
  855.     strcpy(about[0].text, TITLEBAR);
  856.     about[1].text[0] = 0;
  857.     DateTime.dat_Format          = FORMAT_DOS;
  858.     DateTime.dat_Flags           = NULL;
  859.     DateTime.dat_StrDate         = "5-Nov-02";
  860.     DateTime.dat_StrDay          = NULL;
  861.     DateTime.dat_StrTime         = NULL;
  862.     DateTime.dat_Stamp.ds_Minute = 0;
  863.     DateTime.dat_Stamp.ds_Tick   = 0;
  864.     if (StrToDate(&DateTime))
  865.     {   // DateTime.dat_Stamp is now filled
  866.         DateTime.dat_Format  = FORMAT_DEF;
  867.         DateTime.dat_Flags   = NULL;
  868.         DateTime.dat_StrDate = datestring;
  869.         DateTime.dat_StrDay  = weekdaystring;
  870.         DateTime.dat_StrTime = NULL;
  871.         if (DateToStr(&DateTime))
  872.         {   strcpy(about[1].text, weekdaystring);
  873.             strcat(about[1].text, " ");
  874.             strcat(about[1].text, datestring);
  875.     }   }
  876.     strcpy(about[2].text, "© 2002 Amigan Software");
  877.     strcpy(about[3].text, GetCatalogStr(li.li_Catalog, MSG_BY, "By"));
  878.     strcat(about[3].text, " James R. Jacobs");
  879.     monstertypes[0] = GetCatalogStr(li.li_Catalog, MSG_DRAGON, "Dragon");
  880.     monstertypes[1] = GetCatalogStr(li.li_Catalog, MSG_DROW  , "Drow"  );
  881.     monstertypes[2] = GetCatalogStr(li.li_Catalog, MSG_GIANT , "Giant" );
  882.     monstertypes[3] = GetCatalogStr(li.li_Catalog, MSG_GHOST , "Ghost" );
  883.     monstertypes[4] = GetCatalogStr(li.li_Catalog, MSG_TROLL , "Troll" );
  884.     monstertypes[5] = GetCatalogStr(li.li_Catalog, MSG_WITCH , "Witch" );
  885.     runedesc[0] = GetCatalogStr(li.li_Catalog, MSG_THE_GODS, "rune of the gods");
  886.     runedesc[1] = GetCatalogStr(li.li_Catalog, MSG_TIME    , "rune of time"    );
  887.     runedesc[2] = GetCatalogStr(li.li_Catalog, MSG_PROPERTY, "rune of property");
  888.     runedesc[3] = GetCatalogStr(li.li_Catalog, MSG_HEALING , "rune of healing" );
  889.     runedesc[4] = GetCatalogStr(li.li_Catalog, MSG_FURY    , "rune of fury"    );
  890.     runedesc[5] = GetCatalogStr(li.li_Catalog, MSG_THE_SUN , "rune of the sun" );
  891.     for (whichcountry = 36; whichcountry <= 39; whichcountry++)
  892.     {   world[whichcountry].name = GetCatalogStr(li.li_Catalog, MSG_ATLANTIC_OCEAN , "Atlantic Ocean" );
  893.     }
  894.     for (whichcountry = 40; whichcountry <= 42; whichcountry++)
  895.     {   world[whichcountry].name = GetCatalogStr(li.li_Catalog, MSG_IRISH_SEA      , "Irish Sea"      );
  896.     }
  897.     for (whichcountry = 43; whichcountry <= 44; whichcountry++)
  898.     {   world[whichcountry].name = GetCatalogStr(li.li_Catalog, MSG_ENGLISH_CHANNEL, "English Channel");
  899.     }
  900.     for (whichcountry = 45; whichcountry <= 62; whichcountry++)
  901.     {   if (whichcountry < 47 || whichcountry > 48)
  902.         {   world[whichcountry].name = GetCatalogStr(li.li_Catalog, MSG_NORTH_SEA  , "North Sea"      );
  903.     }   }
  904.     for (whichcountry = 63; whichcountry <= 65; whichcountry++)
  905.     {   world[whichcountry].name = GetCatalogStr(li.li_Catalog, MSG_BALTIC_SEA     , "Baltic Sea"     );
  906.     }
  907.     treasure[BROSUNGNECKLACE].name = GetCatalogStr(li.li_Catalog, MSG_BROSUNG_NECKLACE, "Brosung Necklace");
  908.     treasure[MAGICSHIRT].name      = GetCatalogStr(li.li_Catalog, MSG_MAGIC_SHIRT     , "Magic Shirt"     );
  909.     treasure[MAILCOAT].name        = GetCatalogStr(li.li_Catalog, MSG_MAIL_COAT       , "Mail Coat"       );
  910.     NewMenu[0].nm_Label   = GetCatalogStr(li.li_Catalog, MSG_PROJECT         , "Project"   );
  911.     NewMenu[1].nm_Label   = GetCatalogStr(li.li_Catalog, MSG_NEW             , "New"       );
  912.     NewMenu[1].nm_CommKey = GetCatalogStr(li.li_Catalog, MSG_SHORTCUT_NEW    , "N"         );
  913.     NewMenu[2].nm_Label   = GetCatalogStr(li.li_Catalog, MSG_OPEN            , "Open..."   );
  914.     NewMenu[2].nm_CommKey = GetCatalogStr(li.li_Catalog, MSG_SHORTCUT_OPEN   , "O"         );
  915.     NewMenu[4].nm_Label   = GetCatalogStr(li.li_Catalog, MSG_SAVE            , "Save"      );
  916.     NewMenu[4].nm_CommKey = GetCatalogStr(li.li_Catalog, MSG_SHORTCUT_SAVE   , "S"         );
  917.     NewMenu[5].nm_Label   = GetCatalogStr(li.li_Catalog, MSG_SAVE_AS         , "Save As...");
  918.     NewMenu[5].nm_CommKey = GetCatalogStr(li.li_Catalog, MSG_SHORTCUT_SAVE_AS, "A"         );
  919.     NewMenu[7].nm_Label   = GetCatalogStr(li.li_Catalog, MSG_QUIT            , "Quit"      );
  920.     NewMenu[7].nm_CommKey = GetCatalogStr(li.li_Catalog, MSG_SHORTCUT_QUIT   , "Q"         );
  921.     NewMenu[8].nm_Label   = GetCatalogStr(li.li_Catalog, MSG_HELP            , "Help"      );
  922.     NewMenu[9].nm_Label   = GetCatalogStr(li.li_Catalog, MSG_GAME_SUMMARY2   , "Game Summary...");
  923.     NewMenu[9].nm_CommKey = GetCatalogStr(li.li_Catalog, MSG_SHORTCUT_GAME_SUMMARY, "G"    );
  924.     NewMenu[11].nm_Label  = GetCatalogStr(li.li_Catalog, MSG_ABOUT2          , "About..."       );
  925.     SpeedGadget.ng_GadgetText = GetCatalogStr(li.li_Catalog, MSG_MESSAGE_DELAY,"Message Delay:" );
  926.  
  927.     // we run in English if there is a locale problem
  928.  
  929.     resettime();
  930.  
  931.     if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 39L)))
  932.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open graphics.library V39+!\0", 24);
  933.     cleanexit(EXIT_FAILURE);
  934.     }
  935.     if (!(GadToolsBase = (struct GfxBase *) OpenLibrary("gadtools.library", 0L)))
  936.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open gadtools.library!\0", 24);
  937.     cleanexit(EXIT_FAILURE);
  938.     }
  939.     if (!(ASLBase = (struct ASLBase *) OpenLibrary("asl.library", 38L)))
  940.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open ASL.library V38+!\0", 24);
  941.     cleanexit(EXIT_FAILURE);
  942.     }
  943.  
  944.     hero[BEOWULF  ].control = HUMAN;
  945.     hero[BRUNHILD ].control = NONE;
  946.     hero[EGIL     ].control = NONE;
  947.     hero[RAGNAR   ].control = AMIGA;
  948.     hero[SIEGFRIED].control = NONE;
  949.     hero[STARKAD  ].control = NONE;
  950.  
  951.     ok = FALSE;
  952.     if (FileHandle = Open("PROGDIR:Saga.config", MODE_OLDFILE))
  953.     {   if (Read(FileHandle, IOBuffer, 21) == 21)
  954.         {   ok = TRUE;
  955.             for (whichhero = 0; whichhero <= HEROES; whichhero++)
  956.             {   hero[whichhero].control = (SLONG) ((SBYTE) IOBuffer[whichhero]);
  957.             }
  958.             DisplayID     = (ULONG) (  (IOBuffer[ 6] * 16777216)
  959.                                      + (IOBuffer[ 7] *    65536)
  960.                                      + (IOBuffer[ 8] *      256)
  961.                                      +  IOBuffer[ 9]            );
  962.             DisplayWidth  = (ULONG) (  (IOBuffer[10] * 16777216)
  963.                                      + (IOBuffer[11] *    65536)
  964.                                      + (IOBuffer[12] *      256)
  965.                                      +  IOBuffer[13]            );
  966.             DisplayHeight = (ULONG) (  (IOBuffer[14] * 16777216)
  967.                                      + (IOBuffer[15] *    65536)
  968.                                      + (IOBuffer[16] *      256)
  969.                                      +  IOBuffer[17]            );
  970.             DisplayDepth  = (UWORD) (  (IOBuffer[18] *      256)
  971.                                      +  IOBuffer[19]            );
  972.             speed =         (WORD)      IOBuffer[20];
  973.         }
  974.         Close(FileHandle);
  975.         // FileHandle = NULL;
  976.     }
  977.  
  978.     /* argument parsing */
  979.  
  980.     if (argc) /* started from CLI */
  981.     {   if (!(ArgsPtr = ReadArgs
  982.         (   "FILE",
  983.             (LONG *) args,
  984.             NULL
  985.         )))
  986.         {   strcpy(smrstring, GetCatalogStr(li.li_Catalog, MSG_USAGE, "Usage"));
  987.             strcat(smrstring, ": %s [[FILE=]<savedgame>]\n");
  988.             Printf(smrstring, argv[0]);
  989.             cleanexit(EXIT_FAILURE);
  990.         }
  991.         if (args[0])
  992.         {   strcpy(pathname, args[0]);
  993.             cliload = TRUE;
  994.     }   }
  995.  
  996.     strcpy(smrstring, "Saga: ");
  997.     strcat(smrstring, GetCatalogStr(li.li_Catalog, MSG_S_M_R, "Screen Mode Requester"));
  998.  
  999.     if (!ok)
  1000.     {   if (!(smr = (struct ScreenModeRequester *) AllocAslRequestTags
  1001.         (   ASL_ScreenModeRequest,
  1002.             ASLSM_TitleText,            smrstring,
  1003.             ASLSM_InitialDisplayID,     HIRES_KEY | PAL_MONITOR_ID | LACE,
  1004.             ASLSM_InitialDisplayWidth,  SCREENXPIXEL,
  1005.             ASLSM_InitialDisplayHeight, SCREENYPIXEL,
  1006.             ASLSM_InitialDisplayDepth,  DEPTH,
  1007.             ASLSM_DoWidth,              TRUE,
  1008.             ASLSM_DoHeight,             TRUE,
  1009.             ASLSM_DoDepth,              TRUE,
  1010.             ASLSM_MinWidth,             SCREENXPIXEL,
  1011.             ASLSM_MinHeight,            SCREENYPIXEL,
  1012.             ASLSM_MinDepth,             DEPTH,
  1013.             TAG_DONE
  1014.         )))
  1015.         {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't create ASL screen mode request!\0", 24);
  1016.             cleanexit(EXIT_FAILURE);
  1017.         }
  1018.         if (AslRequest(smr, 0L))
  1019.         {   DisplayID     = smr->sm_DisplayID;
  1020.             DisplayWidth  = smr->sm_DisplayWidth;
  1021.             DisplayHeight = smr->sm_DisplayHeight;
  1022.             DisplayDepth  = smr->sm_DisplayDepth;
  1023.         }
  1024.         FreeAslRequest(smr);
  1025.     }
  1026.  
  1027.     ScreenPtr = (struct Screen *) OpenScreenTags
  1028.     (   NULL,
  1029.         SA_Width,       DisplayWidth,
  1030.         SA_Height,      DisplayHeight,
  1031.         SA_Depth,       DisplayDepth,
  1032.         SA_DisplayID,   DisplayID,
  1033.         SA_Title,       TITLEBAR,
  1034.         SA_Font,        &Topaz8,
  1035.         SA_PubName,     "SAGA",
  1036.         SA_Colors32,    table1,
  1037.         SA_Pens,        Pens,
  1038.         SA_Interleaved, TRUE,
  1039.         TAG_DONE
  1040.     );
  1041.     if (!ScreenPtr)
  1042.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open screen!\0", 24);
  1043.         cleanexit(EXIT_FAILURE);
  1044.     }
  1045.     PubScreenStatus(ScreenPtr, NULL); // take the screen public
  1046.  
  1047.     for (whichcountry = 36; whichcountry <= 65; whichcountry++)
  1048.     {   SetRGB32(&ScreenPtr->ViewPort, 8 + whichcountry, 0x00000000, 0x00000000, 0x99999999);
  1049.     }
  1050.     LoadRGB32(&(ScreenPtr->ViewPort), table2);
  1051.  
  1052.     /* GadTools */
  1053.     if (!(VisualInfoPtr = (APTR) GetVisualInfo(ScreenPtr, TAG_DONE)))
  1054.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't get GadTools visual info!\0", 24);
  1055.     cleanexit(EXIT_FAILURE);
  1056.     }
  1057.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  1058.     {   CycleGadget[whichhero].ng_VisualInfo = VisualInfoPtr;
  1059.     }
  1060.     SpeedGadget.ng_VisualInfo = VisualInfoPtr;
  1061.  
  1062.     if (!(MenuPtr = (struct Menu *) CreateMenus(NewMenu, TAG_DONE)))
  1063.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't create menus!\0", 24);
  1064.         cleanexit(EXIT_FAILURE);
  1065.     }
  1066.     if (!(LayoutMenus(MenuPtr, VisualInfoPtr, TAG_DONE)))
  1067.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't lay out menus!\0", 24);
  1068.     cleanexit(EXIT_FAILURE);
  1069.     }
  1070.     if (!(PrevGadgetPtr = (struct Gadget *) CreateContext(&GListPtr)))
  1071.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't create GadTools context!\0", 24);
  1072.     cleanexit(EXIT_FAILURE);
  1073.     }
  1074.  
  1075.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  1076.     {   CycleGadgetPtr[whichhero] = PrevGadgetPtr = (struct Gadget *) CreateGadget
  1077.         (   CYCLE_KIND,
  1078.             PrevGadgetPtr,
  1079.             &CycleGadget[whichhero],
  1080.             GTCY_Labels, CycleOptions,
  1081.             GTCY_Active, hero[whichhero].control,
  1082.             TAG_DONE
  1083.     );
  1084.     }
  1085.     SpeedGadgetPtr = PrevGadgetPtr = (struct Gadget *) CreateGadget
  1086.     (   SLIDER_KIND,
  1087.         PrevGadgetPtr,
  1088.         &SpeedGadget,
  1089.         GA_RelVerify,  TRUE,
  1090.         GTSL_Min,      0,
  1091.         GTSL_Max,      4,
  1092.         GTSL_Level,    speed,
  1093.         GT_Underscore, '_',
  1094.         TAG_DONE
  1095.     );
  1096.  
  1097.     /* main window */
  1098.     if (!(MainWindowPtr = (struct Window *) OpenWindowTags(NULL,
  1099.         WA_Left,                0,
  1100.         WA_Top,                 11,
  1101.         WA_Width,               640,
  1102.         WA_Height,              501,
  1103.         WA_IDCMP,               IDCMP_RAWKEY
  1104.                               | IDCMP_VANILLAKEY
  1105.                               | IDCMP_MOUSEBUTTONS
  1106.                               | IDCMP_INTUITICKS
  1107.                               | IDCMP_CLOSEWINDOW
  1108.                               | IDCMP_REFRESHWINDOW
  1109.                               | IDCMP_MENUPICK
  1110.                               | IDCMP_MENUVERIFY
  1111.                               | CYCLEIDCMP,
  1112.         WA_Flags,               WFLG_BORDERLESS,
  1113.         WA_Gadgets,             GListPtr,
  1114.     WA_CustomScreen,    ScreenPtr,
  1115.     WA_Activate,        TRUE,
  1116.     TAG_DONE)))
  1117.         {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open window!\0", 24);
  1118.             cleanexit(EXIT_FAILURE);
  1119.     }
  1120.  
  1121.     /* redirection of AmigaDOS system requesters */
  1122.     OldWindowPtr = ProcessPtr->pr_WindowPtr;
  1123.     ProcessPtr->pr_WindowPtr = (APTR) MainWindowPtr;
  1124.  
  1125.     if (!(ASLRqPtr = AllocAslRequestTags(ASL_FileRequest, ASL_Pattern, "#?.saga", ASL_Window, MainWindowPtr, TAG_DONE)))
  1126.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't create ASL file request!\0", 24);
  1127.         cleanexit(EXIT_FAILURE);
  1128.     }
  1129.  
  1130.     SetMenuStrip(MainWindowPtr, MenuPtr);
  1131.     createcounters();
  1132.  
  1133.     while (1)
  1134.     {   titlescreen();
  1135.         if (!loaded)
  1136.         {   newgame();
  1137.         }
  1138.         gameloop();
  1139. }   }
  1140.  
  1141. MODULE void gameloop(void)
  1142. {   SLONG countertype,
  1143.           fastest,
  1144.           strongest,
  1145.           strongestjarl,
  1146.           result,
  1147.           whichhero,
  1148.           whichjarl,
  1149.           whichcountry,
  1150.           whichmonster,
  1151.           whichtreasure,
  1152.           whichsord;
  1153.     FLAG  transfer;
  1154.  
  1155.     do
  1156.     {   strcpy(titlestring, TITLEBAR);
  1157.         strcat(titlestring, ": ");
  1158.         strcat(titlestring, GetCatalogStr(li.li_Catalog, MSG_TURN, "Turn"));
  1159.         strcat(titlestring, " ");
  1160.         stcl_d(numberstring, turn);
  1161.         strcat(titlestring, numberstring);
  1162.         strcat(titlestring, " ");
  1163.         strcat(titlestring, GetCatalogStr(li.li_Catalog, MSG_OF, "of"));
  1164.         strcat(titlestring, " ");
  1165.         stcl_d(numberstring, TURNS);
  1166.         strcat(titlestring, numberstring);
  1167.         SetWindowTitles(MainWindowPtr, (UBYTE *) -1, titlestring); // this is not copied, it is a pointer
  1168.  
  1169.         strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_TURN, "Turn"));
  1170.         strcat(saystring, " ");
  1171.         stcl_d(numberstring, turn);
  1172.         strcat(saystring, numberstring);
  1173.         strcat(saystring, " ");
  1174.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_OF, "of"));
  1175.         strcat(saystring, " ");
  1176.         stcl_d(numberstring, TURNS);
  1177.         strcat(saystring, numberstring);
  1178.         strcat(saystring, "...");
  1179.         say(LOWER);
  1180.  
  1181.          OnMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_NEW,          NOSUB));
  1182.          OnMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVE,         NOSUB));
  1183.          OnMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVEAS,       NOSUB));
  1184.         result = getevent(KEYBOARD, NULL);
  1185.         if (result == -4)
  1186.         {   for (whichhero = 0; whichhero <= HEROES; whichhero++)
  1187.             {   hero[whichhero].alive    = FALSE;
  1188.                 hero[whichhero].verydead = TRUE;
  1189.             }
  1190.             gameover = TRUE;
  1191.         }
  1192.         OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_NEW,    NOSUB));
  1193.         OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVE,   NOSUB));
  1194.         OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVEAS, NOSUB));
  1195.  
  1196.         if (!gameover)
  1197.         {
  1198.         for (whichhero = 0; whichhero <= HEROES; whichhero++)
  1199.         {   if (!hero[whichhero].alive && !hero[whichhero].verydead)
  1200.             {   transfer = FALSE;
  1201.                 for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1202.                 {   if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
  1203.                     {   transfer = TRUE;
  1204.                         break; // for speed
  1205.                 }   }
  1206.  
  1207.                 if (hero[whichhero].control == AMIGA)
  1208.                 {   if (transfer)
  1209.                     {   strongest = fastest = 0;
  1210.                         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1211.                         {   if
  1212.                             (   jarl[whichjarl].alive
  1213.                              && jarl[whichjarl].hero == whichhero
  1214.                             )
  1215.                             {   if (jarl[whichjarl].strength > strongest)
  1216.                                 {   strongest     = jarl[whichjarl].strength;
  1217.                                     fastest       = jarl[whichjarl].moves;
  1218.                                     strongestjarl = whichjarl;
  1219.                                 } elif (jarl[whichjarl].strength == strongest)
  1220.                                 {   if (jarl[whichjarl].moves > fastest)
  1221.                                     {   strongest     = jarl[whichjarl].strength;
  1222.                                         fastest       = jarl[whichjarl].moves;
  1223.                                         strongestjarl = whichjarl;
  1224.                         }   }   }   }
  1225.                         promote(whichhero, strongestjarl);
  1226.                         strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_DEAD_HERO, "Dead hero"));
  1227.                         strcat(saystring, " ");
  1228.                         strcat(saystring, hero[whichhero].name);
  1229.                         strcat(saystring, " ");
  1230.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_PROMOTES_JARL, "promotes jarl"));
  1231.                         strcat(saystring, " ");
  1232.                         strcat(saystring, jarl[strongestjarl].name);
  1233.                         strcat(saystring, " (");
  1234.                         stcl_d(numberstring, jarl[strongestjarl].strength);
  1235.                         strcat(saystring, numberstring);
  1236.                         strcat(saystring, "-");
  1237.                         stcl_d(numberstring, jarl[strongestjarl].moves);
  1238.                         strcat(saystring, numberstring);
  1239.                         strcat(saystring, ").");
  1240.                         say(LOWER);
  1241.                         anykey();
  1242.                     } else
  1243.                     {   withdraw(whichhero);
  1244.                         strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_DEAD_HERO, "Dead hero"));
  1245.                         strcat(saystring, " ");
  1246.                         strcat(saystring, hero[whichhero].name);
  1247.                         strcat(saystring, " ");
  1248.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_WITHDRAWS_FROM_PLAY, "withdraws from play"));
  1249.                         strcat(saystring, ".");
  1250.                         say(LOWER);
  1251.                         anykey();
  1252.                 }   }
  1253.                 elif (hero[whichhero].control == HUMAN)
  1254.                 {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_DEAD_HERO, "Dead hero"));
  1255.                     strcat(saystring, " ");
  1256.                     strcat(saystring, hero[whichhero].name);
  1257.                     strcat(saystring, ", (");
  1258.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_WITHDRAW, "W"));
  1259.                     strcat(saystring, ")");
  1260.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_UNCHAR_WITHDRAW, "ithdraw"));
  1261.                     strcat(saystring, "/(");
  1262.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_RESTART, "R"));
  1263.                     strcat(saystring, ")");
  1264.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_UNCHAR_RESTART, "estart"));
  1265.                     if (transfer)
  1266.                     {   strcat(saystring, "/(");
  1267.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_TRANSFER, "T"));
  1268.                         strcat(saystring, ")");
  1269.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_UNCHAR_TRANSFER, "ransfer"));
  1270.                         strcat(saystring, "?");
  1271.                         say(LOWER);
  1272.                         do
  1273.                         {   result = getevent(KEYBOARD, NULL);
  1274.                         } while (result != onekey[ONEKEY_WITHDRAW] && result != onekey[ONEKEY_RESTART] && result != onekey[ONEKEY_TRANSFER]);
  1275.                         if (result == onekey[ONEKEY_TRANSFER])
  1276.                         {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_DEAD_HERO, "Dead hero"));
  1277.                             strcat(saystring, " ");
  1278.                             strcat(saystring, hero[whichhero].name);
  1279.                             strcat(saystring, ", ");
  1280.                             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_W_J_T_P, "select which jarl to promote"));
  1281.                             strcat(saystring, "?");
  1282.                             say(LOWER);
  1283.                             do
  1284.                             {   whichjarl = getevent(COUNTER, &countertype);
  1285.                             } while
  1286.                             (   whichjarl < 0
  1287.                              || countertype != JARL
  1288.                              || jarl[whichjarl].hero != whichhero
  1289.                             );
  1290.                             promote(whichhero, whichjarl);
  1291.                     }   }
  1292.                     else
  1293.                     {   strcat(saystring, "?");
  1294.                         say(LOWER);
  1295.                         do
  1296.                         {   result = getevent(KEYBOARD, NULL);
  1297.                         } while (result != onekey[ONEKEY_WITHDRAW] && result != onekey[ONEKEY_RESTART]);
  1298.                     }
  1299.                     if (result == onekey[ONEKEY_WITHDRAW])
  1300.                     {   withdraw(whichhero);
  1301.                     } elif (result == onekey[ONEKEY_RESTART])
  1302.                     {   newhero(whichhero, FALSE);
  1303.         }   }   }   }
  1304.  
  1305.         phase1(); // movement
  1306.         phase2(); // combat
  1307.         phase3(); // kingdoms
  1308.  
  1309.         /* "4. PLACE MONSTERS. A number of monsters equal to the number
  1310.         of heroes in play are randomly placed face up by rolling two dice
  1311.         and placing the monster in the area indicated. (This is done every
  1312.         turn until all counters are used. "Dead" monsters may not be
  1313.         reused." */
  1314.  
  1315.         place_monsters(); // phase 4
  1316.  
  1317.         /* "5. PLACE jarls. A number of jarls equal to the number of
  1318.         heroes in play are randomly placed face up by rolling two dice
  1319.         and placing the jarl in the area indicated. (This is done every
  1320.         turn until all counters are used. "Dead" jarls may not be
  1321.         reused." */
  1322.  
  1323.         place_jarls();    // phase 5
  1324.  
  1325.         refreshcounters();
  1326.  
  1327.         /* 6. MARK TURN. One turn is marked off. */
  1328.  
  1329.         turn++;
  1330.         }
  1331.     } while (turn <= TURNS && !gameover);
  1332.  
  1333.     /* "At the end of the 20th turn the game is over and players total
  1334.     their glory to determine who has won. The turn should be marked off on
  1335.     each player's record sheet." */
  1336.  
  1337.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  1338.     {   remove_hero(whichhero, FALSE);
  1339.     }
  1340.     for (whichjarl = 0; whichjarl <= JARL; whichjarl++)
  1341.     {   remove_jarl(whichjarl, FALSE);
  1342.     }
  1343.     for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  1344.     {   remove_monster(whichmonster, FALSE);
  1345.     }
  1346.     for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  1347.     {   remove_treasure(whichtreasure, FALSE);
  1348.     }
  1349.     for (whichsord = 0; whichsord <= SORDS; whichsord++)
  1350.     {   remove_sord(whichsord, FALSE);
  1351.     }
  1352.     refreshcounters();
  1353.     for (whichcountry = 0; whichcountry <= 65; whichcountry++)
  1354.     {   world[whichcountry].hero = -1;
  1355.     }
  1356.  
  1357.     if (!gameover)
  1358.     {   SetAPen(MainWindowPtr->RPort, BLACK);
  1359.         RectFill(MainWindowPtr->RPort, 0, 0, SCREENXPIXEL, SCREENYPIXEL);
  1360.  
  1361.         strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_GAME_OVER, "Game over"));
  1362.         strcat(saystring, "!");
  1363.         say(LOWER);                          
  1364.  
  1365.         SetDrMd(MainWindowPtr->RPort, JAM1);
  1366.         for (whichhero = 0; whichhero <= HEROES; whichhero++)
  1367.         {   if (hero[whichhero].control != NONE)
  1368.             {   hero[whichhero].glory += hero[whichhero].wealth / 10;
  1369.                 hero[whichhero].glory += hero[whichhero].luck   /  3;
  1370.                 if
  1371.                 (   treasure[BROSUNGNECKLACE].possessortype == HERO
  1372.                  && treasure[BROSUNGNECKLACE].possessor == whichhero
  1373.                 )
  1374.                 {   hero[whichhero].wealth += 20;
  1375.                 }
  1376.                 for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1377.                 {   if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
  1378.                     {   hero[whichhero].glory += jarl[whichjarl].strength / 2;
  1379.                         if
  1380.                         (   treasure[BROSUNGNECKLACE].possessortype == JARL
  1381.                          && treasure[BROSUNGNECKLACE].possessor == whichjarl
  1382.                         )
  1383.                         {   hero[whichhero].wealth += 20;
  1384.             }   }   }   }
  1385.             if (hero[whichhero].control == NONE)
  1386.             {   SetAPen(MainWindowPtr->RPort, MEDIUMGREY);
  1387.             } elif (hero[whichhero].glory >= 15)
  1388.             {   SetAPen(MainWindowPtr->RPort, GREEN);
  1389.             } else
  1390.             {   SetAPen(MainWindowPtr->RPort, RED);
  1391.             }
  1392.             RectFill(MainWindowPtr->RPort, 320 - 70, 200 + (whichhero * SCOREDISTANCE), 320 + 70, 200 + 11 + (whichhero * SCOREDISTANCE));
  1393.         
  1394.             SetAPen(MainWindowPtr->RPort, BLACK);
  1395.             Move(MainWindowPtr->RPort, 320 - 70 + 4, 200 + 8 + (whichhero * SCOREDISTANCE));
  1396.             Text(MainWindowPtr->RPort, hero[whichhero].name, strlen(hero[whichhero].name));
  1397.         
  1398.             if (hero[whichhero].control == NONE)
  1399.             {   strcpy(numberstring, "-");
  1400.             } else
  1401.             {   stcl_d(numberstring, hero[whichhero].glory);
  1402.                 Move(MainWindowPtr->RPort, 320 + 70 - (8 * 4) - 4 + (8 * (4 - strlen(numberstring))), 200 + 8 + (whichhero * SCOREDISTANCE));
  1403.                 Text(MainWindowPtr->RPort, numberstring, strlen(numberstring));
  1404.         }   }
  1405.         SetAPen(MainWindowPtr->RPort, BLACK);
  1406.         Move(MainWindowPtr->RPort, 340, 200);
  1407.         Draw(MainWindowPtr->RPort, 340, 200 + ((HEROES + 1) * SCOREDISTANCE));
  1408.         
  1409.         clearkybd();
  1410.         waitkey();
  1411. }   }    
  1412.  
  1413. MODULE void callforaid(SLONG passedtype, SLONG passed)
  1414. {   SLONG passedhero, passedwhere, whichjarl;
  1415.  
  1416.     if (passedtype == HERO)
  1417.     {   passedhero = passed;
  1418.         passedwhere = hero[passed].where;
  1419.     } else
  1420.     {   // assert(passedtype == JARL);
  1421.         // assert(jarl[passed].hero != -1);
  1422.         passedhero = jarl[passed].hero;
  1423.         passedwhere = jarl[passed].where;
  1424.     }
  1425.  
  1426.     if (passedtype == JARL && hero[passedhero].where == passedwhere)
  1427.     {   hero[passedhero].defending = TRUE;
  1428.         select_hero(passedhero, FALSE);
  1429.     }
  1430.  
  1431.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1432.     {   if
  1433.         (   jarl[whichjarl].hero == passedhero
  1434.          && jarl[whichjarl].where == passedwhere
  1435.          && !jarl[whichjarl].defending
  1436.         )
  1437.         {   jarl[whichjarl].defending = TRUE;
  1438.             select_jarl(whichjarl, FALSE);
  1439.     }   }
  1440.  
  1441.     refreshcounters();
  1442. }
  1443.  
  1444. MODULE void dobattle(SLONG defendtype, SLONG defender, SLONG attackhero)
  1445. {   SLONG decision,
  1446.           result,
  1447.           attackstrength = 0,
  1448.           attackluck     = 0,
  1449.           attacktype,
  1450.           attacker,
  1451.           defendstrength = 0,
  1452.           defendluck     = 0,
  1453.           defendhero,
  1454.           whichhero,
  1455.           whichjarl,
  1456.           whichsord;
  1457.  
  1458.     /* defendtype: type of defender, one of HERO, JARL, MONSTER or KINGDOM.
  1459.        defender: ordinal number of defender. */
  1460.  
  1461.     if (defendtype == HERO)
  1462.     {   defendhero = defender;
  1463.         hero[defender].defending = TRUE;
  1464.         select_hero(defender, FALSE);
  1465.         callforaid(HERO, defender);
  1466.     } elif (defendtype == JARL)
  1467.     {   defendhero = jarl[defender].hero;
  1468.         jarl[defender].defending = TRUE;
  1469.         if (defendhero != -1)
  1470.         {   select_jarl(defender, FALSE);
  1471.             callforaid(JARL, defender);
  1472.         } else
  1473.         {   select_jarl(defender, TRUE);
  1474.     }   }
  1475.     elif (defendtype == MONSTER)
  1476.     {   defendstrength = monster[defender].strength;
  1477.         defendhero = -1;
  1478.     } else
  1479.     {   // assert(defendtype == KINGDOM);
  1480.         defendstrength = world[defender].tax;
  1481.         defendhero = -1; // even if it already has a king it makes no difference to the combat
  1482.     }
  1483.  
  1484.     // "II. ROLL FOR DROW, WITCH, OR GHOST MAGIC SPELLS (IF APPLICABLE)."
  1485.  
  1486.     if (defendtype == MONSTER)
  1487.     {   if (monster[defender].species == GHOST)
  1488.         {   decision = d6();
  1489.             if (decision <= 3)
  1490.             {   cast(defender, decision);
  1491.         }   }
  1492.         elif (monster[defender].species == DROW)
  1493.         {   cast(defender, d6());
  1494.         } elif (monster[defender].species == WITCH)
  1495.         {   cast(defender, d6());
  1496.             if (attackersleft())
  1497.             {   cast(defender, d6());
  1498.     }   }   }
  1499.  
  1500.     if (!attackersleft())
  1501.     {   // no attackers, abort combat
  1502.         return;
  1503.     }
  1504.  
  1505.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  1506.     {   if (hero[whichhero].attacking)
  1507.         {   attackstrength += hero[whichhero].strength;
  1508.         } elif (hero[whichhero].defending)
  1509.         {   defendstrength += hero[whichhero].strength;
  1510.     }   }
  1511.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1512.     {   if (jarl[whichjarl].attacking)
  1513.         {   attackstrength += jarl[whichjarl].strength;
  1514.         } elif (jarl[whichjarl].defending)
  1515.         {   defendstrength += jarl[whichjarl].strength;
  1516.     }   }
  1517.  
  1518.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  1519.     {   if (hero[whichhero].attacking && hero[whichhero].hagall)
  1520.         {   attackstrength--;
  1521.         } elif (hero[whichhero].defending && hero[whichhero].hagall)
  1522.         {   defendstrength--;
  1523.     }   }
  1524.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1525.     {   if (jarl[whichjarl].attacking && jarl[whichjarl].hagall)
  1526.         {   attackstrength--;
  1527.         } elif (jarl[whichjarl].defending && jarl[whichjarl].hagall)
  1528.         {   defendstrength--;
  1529.     }   }
  1530.     if (defendtype == MONSTER && monster[defender].hagall)
  1531.     {   defendstrength--;
  1532.     }
  1533.  
  1534.     /* "III. MODIFY THE DIE ROLL WITH LUCK. Before the die is rolled,
  1535.     heroes who are involved in the battle (or who have jarls involved in
  1536.     the battle) may modify the die roll up or down one with each point of
  1537.     luck expended before the die is rolled. If there are two or more
  1538.     heroes involved in the battle they should each write how much luck
  1539.     they are using to modify the die roll and how before revealing the
  1540.     amounts simultaneously." */
  1541.  
  1542.     if (hero[attackhero].luck >= 1)
  1543.     {   if (hero[attackhero].control == HUMAN)
  1544.         {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_ATTACKING, "Attacking"));
  1545.             saywho(HERO, attackhero, FALSE, TRUE);
  1546.             strcat(saystring, ", ");
  1547.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_USE_LUCK, "use luck"));
  1548.             strcat(saystring, " (0-");
  1549.             if (hero[attackhero].luck >= 9)
  1550.             {   strcat(saystring, "9");
  1551.             } else
  1552.             {   stcl_d(numberstring, hero[attackhero].luck);
  1553.                 strcat(saystring, numberstring);
  1554.             }
  1555.             strcat(saystring, ")?");
  1556.             say(LOWER);
  1557.             attackstrength += getluck(attackhero);
  1558.         } else
  1559.         {   // assert(hero[attackhero].control == AMIGA);
  1560.             attackluck = 0;
  1561.     }   }
  1562.  
  1563.     if (defendhero != -1)
  1564.     {   if (hero[defendhero].control == HUMAN)
  1565.         {   if (hero[defendhero].luck >= 1)
  1566.             {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_DEFENDING, "Defending"));
  1567.                 saywho(defendtype, defender, FALSE, TRUE);
  1568.                 strcat(saystring, ", ");
  1569.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_USE_LUCK, "use luck"));
  1570.                 strcat(saystring, " (0-");
  1571.                 if (hero[defendhero].luck >= 9)
  1572.                 {   strcat(saystring, "9");
  1573.                 } else
  1574.                 {   stcl_d(numberstring, hero[defendhero].luck);
  1575.                     strcat(saystring, numberstring);
  1576.                 }
  1577.                 strcat(saystring, ")?");
  1578.                 say(LOWER);
  1579.                 defendstrength += getluck(defendhero);
  1580.         }   }
  1581.         else
  1582.         {   // assert(hero[defendhero].control == AMIGA);
  1583.             defendluck = 0;
  1584.     }   }
  1585.  
  1586. /*  if (hero[attackhero].control == AMIGA && attackluck > 0)
  1587.     {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_ATTACKING, "Attacking"));
  1588.         saywho(HERO, attackhero, FALSE, TRUE);
  1589.         strcat(saystring, " ");
  1590.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_USED, "used"));
  1591.         strcat(saystring, " ");
  1592.         stcl_d(numberstring, attackluck);
  1593.         strcat(saystring, numberstring);
  1594.         strcat(saystring, " ");
  1595.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_LUCK2, "luck"));
  1596.         strcat(saystring, ".");
  1597.         say(LOWER);
  1598.         anykey();
  1599.     }
  1600.     if (defendhero != -1)
  1601.     {   if (hero[defendhero].control == AMIGA && defendluck > 0)
  1602.         {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_DEFENDING, "Defending"));
  1603.             saywho(HERO, defendhero, FALSE, TRUE);
  1604.             strcat(saystring, ", ");
  1605.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_USED, "used"));
  1606.             strcat(saystring, " ");
  1607.             stcl_d(numberstring, defendluck);
  1608.             strcat(saystring, numberstring);
  1609.             strcat(saystring, " ");
  1610.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_LUCK2, "luck"));
  1611.             strcat(saystring, ".");
  1612.             say(LOWER);
  1613.             anykey();
  1614.     }   } */
  1615.  
  1616.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  1617.     {   if (hero[whichhero].alive && hero[whichhero].rune == OGAL)
  1618.         {   if (hero[whichhero].attacking)
  1619.             {   attackstrength++;
  1620.             } elif (hero[whichhero].defending)
  1621.             {   defendstrength++;
  1622.     }   }   }
  1623.  
  1624.     for (whichsord = 0; whichsord <= SORDS; whichsord++)
  1625.     {   if
  1626.         (   (   sord[whichsord].possessortype == HERO
  1627.              && hero[sord[whichsord].possessor].attacking
  1628.             )
  1629.          || (   sord[whichsord].possessortype == JARL
  1630.              && jarl[sord[whichsord].possessor].attacking
  1631.         )   )
  1632.         {   if (whichsord == BALMUNG || whichsord == HRUNTING)
  1633.             {   attackstrength++;
  1634.             } elif (whichsord == DRAGVENDILL || whichsord == GRAM || whichsord == TYRFING)
  1635.             {   attackstrength += 2;
  1636.             } elif (whichsord == LOVI)
  1637.             {   attackstrength++;
  1638.                 for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1639.                 {   if (jarl[whichjarl].defending)
  1640.                     {   attackstrength += 2;
  1641.                         break;
  1642.         }   }   }   }
  1643.         elif
  1644.         (   (   sord[whichsord].possessortype == HERO
  1645.              && hero[sord[whichsord].possessor].defending
  1646.             )
  1647.          || (   sord[whichsord].possessortype == JARL
  1648.              && jarl[sord[whichsord].possessor].defending
  1649.         )   )
  1650.         {   if (whichsord == BALMUNG || whichsord == HRUNTING)
  1651.             {   defendstrength++;
  1652.             } elif (whichsord == DRAGVENDILL || whichsord == GRAM || whichsord == TYRFING)
  1653.             {   defendstrength += 2;
  1654.             } elif (whichsord == LOVI)
  1655.             {   defendstrength++;
  1656.                 for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1657.                 {   if (jarl[whichjarl].attacking)
  1658.                     {   defendstrength += 2;
  1659.                         break;
  1660.     }   }   }   }   }
  1661.  
  1662.     if (hero[attackhero].attacking)
  1663.     {   attackstrength += odin_tyr(attackhero, TRUE);
  1664.         if (attackstrength < 0)
  1665.         {   attackstrength = 0;
  1666.     }   }
  1667.     if (defendhero != -1 && hero[defendhero].defending)
  1668.     {   defendstrength += odin_tyr(defendhero, FALSE);
  1669.         if (defendstrength < 0)
  1670.         {   defendstrength = 0;
  1671.     }   }
  1672.  
  1673.     if
  1674.     (   (   sord[BALMUNG].possessortype == HERO
  1675.          && hero[sord[BALMUNG].possessor].attacking
  1676.         )
  1677.      || (   sord[BALMUNG].possessortype == JARL
  1678.          && jarl[sord[BALMUNG].possessor].attacking
  1679.     )   )
  1680.     {   ; // one of the attackers is wielding Balmung
  1681.         // assert(sord[BALMUNG].where == -1);
  1682.     } else
  1683.     {   if
  1684.         (   (   treasure[MAGICSHIRT].possessortype == HERO
  1685.              && hero[treasure[MAGICSHIRT].possessor].defending
  1686.             )
  1687.          || (   treasure[MAGICSHIRT].possessortype == JARL
  1688.              && jarl[treasure[MAGICSHIRT].possessor].defending
  1689.         )   )
  1690.         {   // one of the defenders is wearing the Magic Shirt
  1691.             // assert(treasure[MAGICSHIRT].where == -1);
  1692.  
  1693.             defendstrength++;
  1694.         }
  1695.  
  1696.         if
  1697.         (   (   treasure[MAILCOAT].possessortype == HERO
  1698.              && hero[treasure[MAILCOAT].possessor].defending
  1699.             )
  1700.          || (   treasure[MAILCOAT].possessortype == JARL
  1701.              && jarl[treasure[MAILCOAT].possessor].defending
  1702.         )   )
  1703.         {   // one of the defenders is wearing the Mail Coat
  1704.             // assert(treasure[MAILCOAT].where == -1);
  1705.  
  1706.             defendstrength += 2;
  1707.     }   }
  1708.  
  1709.     /* "V. ROLL ONE DIE AND CHECK THE COMBAT RESULTS TABLE TO DETERMINE
  1710.     THE OUTCOME OF THE BATTLE AFTER ADDING ALL MODIFIERS TO THE DIE ROLL.
  1711.     After all modifications to the combat strengths of both sides have
  1712.     been made, subtract the defender's strength from the attacker's and
  1713.     consult the COMBAT RESULTS TABLE below to determine the results
  1714.     according to a die roll and modifications due to luck." */
  1715.  
  1716. /*
  1717. Printf("Involved in the combat are:\n");
  1718. Printf(" Attackers:\n");
  1719. if (hero[attackhero].attacking)
  1720. {   Printf("  Hero %s!\n", hero[attackhero].name);
  1721. }
  1722. for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1723. {   if (jarl[whichjarl].attacking)
  1724.     {   Printf("  Jarl %s!\n", jarl[whichjarl].name);
  1725. }   }
  1726. Printf(" Defenders:\n");
  1727. if (defendhero != -1)
  1728. {   if (hero[defendhero].defending)
  1729.     {   Printf("  Hero %s!\n", hero[defendhero].name);
  1730. }   }
  1731. for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1732. {   if (jarl[whichjarl].defending)
  1733.     {   Printf("  Jarl %s!\n", jarl[whichjarl].name);
  1734. }   }
  1735. if (defendhero == -1)
  1736. {   if (defendtype == KINGDOM)
  1737.     {   Printf("  Kingdom %s!\n", world[defender].name);
  1738.     } elif (defendtype == MONSTER)
  1739.     {   Printf("  Monster %s!\n", monster[defender].name);
  1740. }   }
  1741. */
  1742.  
  1743.     result = attackstrength - defendstrength + d6();
  1744.  
  1745.     if (result == 4) // attacker flees
  1746.     {   if (sord[HRUNTING].possessortype == HERO)
  1747.         {   if (hero[sord[HRUNTING].possessor].attacking)
  1748.             {   result = 6; // defender flees
  1749.         }   }
  1750.         elif (sord[HRUNTING].possessortype == JARL)
  1751.         {   if (jarl[sord[HRUNTING].possessor].attacking)
  1752.             {   result = 6; // defender flees
  1753.     }   }   }
  1754.     elif (result == 6) // defender flees
  1755.     {   if (sord[HRUNTING].possessortype == HERO)
  1756.         {   if (hero[sord[HRUNTING].possessor].defending)
  1757.             {   result = 4; // attacker flees
  1758.         }   }
  1759.         elif (sord[HRUNTING].possessortype == JARL)
  1760.         {   if (jarl[sord[HRUNTING].possessor].defending)
  1761.             {   result = 4; // attacker flees
  1762.     }   }   }
  1763.  
  1764.     /* "VI. APPLY THE COMBAT RESULT." */
  1765.  
  1766.     if (hero[attackhero].attacking)
  1767.     {   attacktype = HERO;
  1768.         attacker   = attackhero;
  1769.     } else
  1770.     {   attacktype = JARL; // uses the first jarl found
  1771.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1772.         {   if (jarl[whichjarl].attacking)
  1773.             {   attacker = whichjarl;
  1774.                 break;
  1775.     }   }   }
  1776.  
  1777.     if (result <= 2) // attackers killed
  1778.     {   if (hero[attackhero].attacking)
  1779.         {   kill(defendtype, defender, defendhero, HERO, attackhero, attackhero);
  1780.         }
  1781.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1782.         {   if (jarl[whichjarl].attacking)
  1783.             {   kill(defendtype, defender, defendhero, JARL, whichjarl, attackhero);
  1784.     }   }   }
  1785.     elif (result == 3) // attackers wounded
  1786.     {   if (hero[attackhero].attacking)
  1787.         {   wound(defendtype, defender, defendhero, HERO, attackhero, attackhero);
  1788.         }
  1789.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1790.         {   if (jarl[whichjarl].attacking)
  1791.             {   wound(defendtype, defender, defendhero, JARL, whichjarl, attackhero);
  1792.     }   }   }
  1793.     elif (result == 4) // attackers flee
  1794.     {   if (hero[attackhero].attacking)
  1795.         {   flee(defendtype, defender, defendhero, HERO, attackhero, attackhero);
  1796.         }
  1797.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1798.         {   if (jarl[whichjarl].attacking)
  1799.             {   flee(defendtype, defender, defendhero, JARL, whichjarl, attackhero);
  1800.     }   }   }
  1801.     elif (result == 5) // no result
  1802.     {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_NO_RESULT, "No result"));
  1803.         strcat(saystring, ".");
  1804.         say(LOWER);
  1805.         anykey();
  1806.     } elif (result == 6) // defenders flee
  1807.     {   if (defendtype == MONSTER || defendtype == KINGDOM)
  1808.         {   flee(attacktype, attacker, attackhero, defendtype, defender, -1);
  1809.         } else
  1810.         {   assert(defendtype == HERO || defendtype == JARL);
  1811.             if (defendhero != -1 && hero[defendhero].defending)
  1812.             {   flee(attacktype, attacker, attackhero, HERO, defendhero, defendhero);
  1813.             }
  1814.             for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1815.             {   if (jarl[whichjarl].defending)
  1816.                 {   flee(attacktype, attacker, attackhero, JARL, whichjarl, defendhero);
  1817.     }   }   }   }
  1818.     elif (result == 7) // defenders wounded
  1819.     {   if (defendtype == MONSTER || defendtype == KINGDOM)
  1820.         {   wound(attacktype, attacker, attackhero, defendtype, defender, -1);
  1821.         } else
  1822.         {   assert(defendtype == HERO || defendtype == JARL);
  1823.             if (defendhero != -1 && hero[defendhero].defending)
  1824.             {   wound(attacktype, attacker, attackhero, HERO, defendhero, defendhero);
  1825.             }
  1826.             for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1827.             {   if (jarl[whichjarl].defending)
  1828.                 {   wound(attacktype, attacker, attackhero, JARL, whichjarl, defendhero);
  1829.     }   }   }   }
  1830.     else // defenders killed
  1831.     {   // assert(result >= 8);
  1832.         if (defendtype == MONSTER || defendtype == KINGDOM)
  1833.         {   kill(attacktype, attacker, attackhero, defendtype, defender, -1);
  1834.         } else
  1835.         {   assert(defendtype == HERO || defendtype == JARL);
  1836.             if (defendhero != -1 && hero[defendhero].defending)
  1837.             {   kill(attacktype, attacker, attackhero, HERO, defendhero, defendhero);
  1838.             }
  1839.             for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1840.             {   if (jarl[whichjarl].defending)
  1841.                 {   kill(attacktype, attacker, attackhero, JARL, whichjarl, defendhero);
  1842.     }   }   }   }
  1843.  
  1844.     if (hero[attackhero].attacking)
  1845.     {   thor(attackhero);
  1846.     }
  1847.     if (defendhero != -1 && hero[defendhero].defending && hero[defendhero].alive)
  1848.     {   thor(defendhero);
  1849.     }
  1850.  
  1851.     if (hero[attackhero].attacking)
  1852.     {   pray(attackhero);
  1853.     }
  1854.     if (defendhero != -1 && hero[defendhero].defending && hero[defendhero].alive)
  1855.     {   pray(defendhero);
  1856.     }
  1857.  
  1858.     if (hero[attackhero].attacking)
  1859.     {   deselect_hero(attackhero, FALSE);
  1860.         hero[attackhero].attacking = FALSE;
  1861.     } elif (hero[defendhero].defending)
  1862.     {   deselect_hero(defendhero, FALSE);
  1863.         hero[defendhero].defending = FALSE;
  1864.     }
  1865.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  1866.     {   if (jarl[whichjarl].attacking)
  1867.         {   deselect_jarl(whichjarl, FALSE);
  1868.             jarl[whichjarl].attacking   =
  1869.             jarl[whichjarl].recruitable = FALSE;
  1870.         } elif (jarl[whichjarl].defending)
  1871.         {   deselect_jarl(whichjarl, FALSE);
  1872.             jarl[whichjarl].defending   =
  1873.             jarl[whichjarl].recruitable = FALSE;
  1874.     }   }
  1875.     refreshcounters();
  1876. }
  1877.  
  1878. MODULE void flee(SLONG routertype, SLONG router, SLONG routerhero, SLONG routedtype, SLONG routed, SLONG routedhero)
  1879. {   if (routedtype == HERO)
  1880.     {   hero[routed].glory -= 2;
  1881.         if (hero[routed].glory < 0)
  1882.         {   hero[routed].glory = 0;
  1883.     }   }
  1884.  
  1885.     if (routertype == HERO || routertype == JARL)
  1886.     {   if (routedtype == KINGDOM)
  1887.         {   world[routed].hero = routerhero;
  1888.             darken();
  1889.             saywho(routertype, router, FALSE, FALSE);
  1890.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HAS_CONQUERED_KINGDOM, "has conquered kingdom"));
  1891.             strcat(saystring, " ");
  1892.             strcat(saystring, world[routed].name);
  1893.             strcat(saystring, " (");
  1894.             stcl_d(numberstring, world[routed].tax);
  1895.             strcat(saystring, numberstring);
  1896.             strcat(saystring, ").");
  1897.             say(LOWER);
  1898.             anykey();
  1899.         } elif (routedtype == JARL)
  1900.         {   if
  1901.             (   routerhero != -1
  1902.              && hero[routerhero].where == jarl[routed].where
  1903.              && !recruit(routed, routerhero)
  1904.             )
  1905.             {   saywho(JARL, routed, FALSE, FALSE);
  1906.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_ROUTED, "is routed"));
  1907.                 strcat(saystring, "!");
  1908.                 say(LOWER);
  1909.                 anykey();
  1910.  
  1911.                 if (routertype == HERO)
  1912.                 {   if (hero[router].control == AMIGA)
  1913.                     {   amiga_rout(JARL, routed);
  1914.                     } else
  1915.                     {   // assert(hero[router].control == HUMAN);
  1916.                         human_rout(JARL, routed, routerhero);
  1917.                 }   }
  1918.                 else
  1919.                 {   // assert(routertype == JARL);
  1920.                     if (jarl[router].hero == -1 || hero[jarl[router].hero].control == AMIGA)
  1921.                     {   amiga_rout(JARL, routed);
  1922.                     } else
  1923.                     {   human_rout(JARL, routed, routerhero);
  1924.         }   }   }   }
  1925.         elif (routedtype == HERO)
  1926.         {   saywho(HERO, routed, FALSE, FALSE);
  1927.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_ROUTED, "is routed"));
  1928.             strcat(saystring, "!");
  1929.             say(LOWER);
  1930.             anykey();
  1931.  
  1932.             if (routertype == HERO)
  1933.             {   if (hero[router].control == AMIGA)
  1934.                 {   amiga_rout(HERO, routed);
  1935.                 } else
  1936.                 {   // assert(hero[router].control == HUMAN);
  1937.                     human_rout(HERO, routed, routerhero);
  1938.             }   }
  1939.             else
  1940.             {   // assert(routertype == JARL);
  1941.                 if (jarl[router].hero == -1 || hero[jarl[router].hero].control == AMIGA)
  1942.                 {   amiga_rout(HERO, routed);
  1943.                 } else
  1944.                 {   human_rout(HERO, routed, routerhero);
  1945.         }   }   }
  1946.         elif (routedtype == MONSTER)
  1947.         {   strcpy(saystring, monstertypes[monster[routed].species]);
  1948.             strcat(saystring, " ");
  1949.             strcat(saystring, monster[routed].name);
  1950.             strcat(saystring, " ");
  1951.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_ROUTED, "is routed"));
  1952.             strcat(saystring, "!");
  1953.             say(LOWER);
  1954.             anykey();
  1955.  
  1956.             if (routertype == HERO)
  1957.             {   if (hero[router].control == AMIGA)
  1958.                 {   amiga_rout(MONSTER, routed);
  1959.                 } else
  1960.                 {   // assert(hero[router].control == HUMAN);
  1961.                     human_rout(MONSTER, routed, routerhero);
  1962.             }   }
  1963.             else
  1964.             {   // assert(routertype == JARL);
  1965.                 if (jarl[router].hero == -1 || hero[jarl[router].hero].control == AMIGA)
  1966.                 {   amiga_rout(MONSTER, routed);
  1967.                 } else
  1968.                 {   human_rout(MONSTER, routed, routerhero);
  1969.     }   }   }   }
  1970.     else
  1971.     {   // assert(routertype == MONSTER || routertype == KINGDOM);
  1972.         if (routedtype == JARL)
  1973.         {   saywho(JARL, routed, FALSE, FALSE);
  1974.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_ROUTED, "is routed"));
  1975.             strcat(saystring, "!");
  1976.             say(LOWER);
  1977.             anykey();
  1978.  
  1979.             amiga_rout(JARL, routed);
  1980.         } elif (routedtype == HERO)
  1981.         {   saywho(HERO, routed, FALSE, FALSE);
  1982.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_ROUTED, "is routed"));
  1983.             strcat(saystring, "!");
  1984.             say(LOWER);
  1985.             anykey();
  1986.  
  1987.             amiga_rout(HERO, routed);
  1988. }   }   }
  1989.  
  1990. MODULE void wound(SLONG woundertype, SLONG wounder, SLONG wounderhero, SLONG woundedtype, SLONG wounded, SLONG woundedhero)
  1991. {   SLONG glory = 0, luck = 0, whichtreasure, whichsord;
  1992.  
  1993.     /* WOUNDED. Heroes on the wounded side are wounded.
  1994.     Jarls on the wounded side are removed from the board and placed,
  1995.     upside down, in their respective piles, from which they will reenter
  1996.     play normally. There is no further effect from being wounded, except
  1997.     that jarls that reenter play after being wounded are to be considered
  1998.     unrecruited jarls. */
  1999.  
  2000.     if (woundedtype == HERO)
  2001.     {   if (hero[wounded].wounded)
  2002.         {   kill(woundertype, wounder, wounderhero, woundedtype, wounded, woundedhero);
  2003.             return;
  2004.         }
  2005.  
  2006.         hero[wounded].wounded = TRUE;
  2007.         saywho(HERO, wounded, FALSE, FALSE);
  2008.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_WOUNDED, "is wounded"));
  2009.         strcat(saystring, "!");
  2010.         say(LOWER);
  2011.         anykey();
  2012.  
  2013.         if (hero[wounded].maidens)
  2014.         {   hero[wounded].maidens--;
  2015.             hero[wounded].wounded = FALSE;
  2016.  
  2017.             strcpy(saystring, "Frey ");
  2018.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_SENDS_A_MAIDEN_TO_HEAL_HERO, "Frey sends a maiden to heal hero"));
  2019.             strcat(saystring, " ");
  2020.             strcat(saystring, hero[wounded].name);
  2021.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_WOUND, "'s wound"));
  2022.             strcat(saystring, ".");
  2023.             say(LOWER);
  2024.             anykey();
  2025.         }
  2026.  
  2027.         if (wounderhero != -1)
  2028.         {   gain(wounderhero, hero[woundedhero].strength / 2 / 2, hero[woundedhero].strength / 2 / 2);
  2029.     }   }
  2030.     elif (woundedtype == JARL)
  2031.     {   if
  2032.         (   wounderhero != -1
  2033.          && hero[wounderhero].where == jarl[wounded].where
  2034.          && recruit(wounded, wounderhero)
  2035.         )
  2036.         {   return;
  2037.         }
  2038.  
  2039.         jarl[wounded].alive  = FALSE;
  2040.         jarl[wounded].taken  = FALSE;
  2041.         jarl[wounded].hero   = -1;
  2042.         jarl[wounded].wealth = 0; // this is actually an ambiguity in the rules
  2043.         remove_jarl(wounded, TRUE);
  2044.          
  2045.         for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  2046.         {   if
  2047.             (   treasure[whichtreasure].possessortype == JARL
  2048.              && treasure[whichtreasure].possessor == wounded
  2049.             )
  2050.             {   // drop the treasure
  2051.                 treasure[whichtreasure].possessortype = KINGDOM;
  2052.                 treasure[whichtreasure].possessor     = -1;
  2053.                 treasure[whichtreasure].where         = jarl[wounded].where;
  2054.                 move_treasure(whichtreasure, TRUE);
  2055.         }   }
  2056.         for (whichsord = 0; whichsord <= SORDS; whichsord++)
  2057.         {   if
  2058.             (   sord[whichsord].possessortype == JARL
  2059.              && sord[whichsord].possessor == wounded
  2060.             )
  2061.             {   // drop the sword
  2062.                 sord[whichsord].possessortype = KINGDOM;
  2063.                 sord[whichsord].possessor     = -1;
  2064.                 sord[whichsord].where         = jarl[wounded].where;
  2065.                 move_sord(whichsord, TRUE);
  2066.         }   }
  2067.  
  2068.         saywho(JARL, wounded, FALSE, FALSE);
  2069.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_WOUNDED, "is wounded"));
  2070.         strcat(saystring, "!");
  2071.         say(LOWER);
  2072.         anykey();
  2073.  
  2074.         if (wounderhero != -1)
  2075.         {   gain(wounderhero, jarl[wounded].strength / 2 / 2, jarl[wounded].strength / 2 / 2); // not the same as / 4 due to rounding
  2076.     }   }
  2077.     elif (woundedtype == KINGDOM)
  2078.     {   world[wounded].hero = wounderhero;
  2079.         darken();
  2080.  
  2081.         saywho(woundertype, wounder, FALSE, FALSE);
  2082.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HAS_CONQUERED_KINGDOM, "has conquered kingdom"));
  2083.         strcat(saystring, " ");
  2084.         strcat(saystring, world[wounded].name);
  2085.         strcat(saystring, " (");
  2086.         stcl_d(numberstring, world[wounded].tax);
  2087.         strcat(saystring, numberstring);
  2088.         strcat(saystring, ").");
  2089.         say(LOWER);
  2090.         anykey();
  2091.     } elif (woundedtype == MONSTER)
  2092.     {   monster[wounded].alive = FALSE;
  2093.         monster[wounded].taken = FALSE;
  2094.         remove_monster(wounded, TRUE);
  2095.  
  2096.         strcpy(saystring, monstertypes[monster[wounded].species]);
  2097.         strcat(saystring, " ");
  2098.         strcat(saystring, monster[wounded].name);
  2099.         strcat(saystring, " ");
  2100.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_WOUNDED, "is wounded"));
  2101.         strcat(saystring, "!");
  2102.         say(LOWER);
  2103.         anykey();
  2104.        
  2105.         for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  2106.         {   if
  2107.             (   treasure[whichtreasure].possessortype == MONSTER
  2108.              && treasure[whichtreasure].possessor == wounded
  2109.             )
  2110.             {   // give the treasure to the wounder of the dragon
  2111.                 // assert(monster[wounded].species == DRAGON);
  2112.                 treasure[whichtreasure].possessortype = woundertype;
  2113.                 treasure[whichtreasure].possessor     = wounder;
  2114.                 treasure[whichtreasure].where         = -1;
  2115.  
  2116.                 saywho(woundertype, wounder, FALSE, FALSE);
  2117.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FINDS_THE, "finds the"));
  2118.                 strcat(saystring, " ");
  2119.                 strcat(saystring, treasure[whichtreasure].name);
  2120.                 strcat(saystring, ".");
  2121.                 say(LOWER);
  2122.                 anykey();
  2123.         }   }
  2124.  
  2125.         if (monster[wounded].wealth > 0)
  2126.         {   hero[wounderhero].wealth += monster[wounded].wealth;
  2127.  
  2128.             saywho(woundertype, wounder, FALSE, FALSE);
  2129.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FINDS, "finds"));
  2130.             strcat(saystring, " ");
  2131.             stcl_d(numberstring, monster[wounded].wealth);
  2132.             strcat(saystring, numberstring);
  2133.             strcat(saystring, " ");
  2134.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS, "golden marks"));
  2135.             strcat(saystring, ".");
  2136.             say(LOWER);
  2137.             anykey();
  2138.         }
  2139.  
  2140.         switch (monster[wounded].species)
  2141.         {
  2142.         case DRAGON:
  2143.             glory = 6;
  2144.             luck  = 5;
  2145.         break;
  2146.         case DROW:
  2147.             glory = 3;
  2148.             luck  = 2;
  2149.         break;
  2150.         case GHOST:
  2151.             glory = 2;
  2152.             luck  = 2;
  2153.         break;
  2154.         case GIANT:
  2155.             glory = 4;
  2156.             luck  = 3;
  2157.         break;
  2158.         case TROLL:
  2159.             glory = 3;
  2160.             luck  = 3;
  2161.         break;
  2162.         case WITCH:
  2163.             glory = 5;
  2164.             luck  = 4;
  2165.         break;
  2166.         default:
  2167.             // assert(0);
  2168.         break;
  2169.         }
  2170.         glory /= 2;
  2171.         luck  /= 2;
  2172.  
  2173.         // assert(wounderhero != -1);
  2174.         gain(wounderhero, glory, luck);
  2175. }   }
  2176. MODULE void kill(SLONG killertype, SLONG killer, SLONG killerhero, SLONG killedtype, SLONG killed, SLONG killedhero)
  2177. {   SLONG glory = 0, luck = 0, result, whichjarl, whichtreasure, whichsord;
  2178.  
  2179.     if (killedtype == HERO)
  2180.     {   hero[killed].alive     =
  2181.         hero[killed].attacking =
  2182.         hero[killed].defending = FALSE;
  2183.         remove_hero(killed, TRUE);
  2184.  
  2185.         for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  2186.         {   if
  2187.             (   treasure[whichtreasure].possessortype == HERO
  2188.              && treasure[whichtreasure].possessor == killed
  2189.             )
  2190.             {   // drop the treasure
  2191.                 treasure[whichtreasure].possessortype = KINGDOM;
  2192.                 treasure[whichtreasure].possessor     = -1;
  2193.                 treasure[whichtreasure].where         = hero[killed].where;
  2194.                 move_treasure(whichtreasure, TRUE);
  2195.         }   }
  2196.         for (whichsord = 0; whichsord <= SORDS; whichsord++)
  2197.         {   if
  2198.             (   sord[whichsord].possessortype == HERO
  2199.              && sord[whichsord].possessor == killed
  2200.             )
  2201.             {   // drop the sword
  2202.                 sord[whichsord].possessortype = KINGDOM;
  2203.                 sord[whichsord].possessor     = -1;
  2204.                 sord[whichsord].where         = hero[killed].where;
  2205.                 move_sord(whichsord, TRUE);
  2206.         }   }
  2207.  
  2208.         saywho(HERO, killed, FALSE, FALSE);
  2209.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_KILLED, "is killed"));
  2210.         strcat(saystring, "!");
  2211.         say(LOWER);
  2212.         anykey();
  2213.  
  2214.         if (killerhero != -1)
  2215.         {   gain(killerhero, hero[killedhero].strength / 2, hero[killedhero].strength / 2);
  2216.     }   }
  2217.     elif (killedtype == JARL)
  2218.     {   if
  2219.         (   killerhero == -1
  2220.          || hero[killerhero].where != jarl[killed].where
  2221.          || !recruit(killed, killerhero)
  2222.         )
  2223.         {   jarl[killed].alive     =
  2224.             jarl[killed].attacking =
  2225.             jarl[killed].defending = FALSE;
  2226.             remove_jarl(killed, TRUE);
  2227.             
  2228.             for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  2229.             {   if
  2230.                 (   treasure[whichtreasure].possessortype == JARL
  2231.                  && treasure[whichtreasure].possessor == killed
  2232.                 )
  2233.                 {   // drop the treasure
  2234.                     treasure[whichtreasure].possessortype = KINGDOM;
  2235.                     treasure[whichtreasure].possessor     = -1;
  2236.                     treasure[whichtreasure].where         = jarl[killed].where;
  2237.                     move_treasure(whichtreasure, TRUE);
  2238.             }   }
  2239.             for (whichsord = 0; whichsord <= SORDS; whichsord++)
  2240.             {   if
  2241.                 (   sord[whichsord].possessortype == JARL
  2242.                  && sord[whichsord].possessor == killed
  2243.                 )
  2244.                 {   // drop the treasure
  2245.                     sord[whichsord].possessortype = KINGDOM;
  2246.                     sord[whichsord].possessor     = -1;
  2247.                     sord[whichsord].where         = jarl[killed].where;
  2248.                     move_sord(whichsord, TRUE);
  2249.             }   }
  2250.  
  2251.             saywho(JARL, killed, FALSE, FALSE);
  2252.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_KILLED, "is killed"));
  2253.             strcat(saystring, "!");
  2254.             say(LOWER);
  2255.             anykey();
  2256.  
  2257.             if (killerhero != -1 && killedtype == JARL)
  2258.             {   if (hero[killerhero].where == jarl[killed].where)
  2259.                 {   if (jarl[killed].wealth)
  2260.                     {   hero[killerhero].wealth += jarl[killed].wealth;
  2261.                         saywho(HERO, killerhero, FALSE, FALSE);
  2262.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES, "takes"));
  2263.                         strcat(saystring, " ");
  2264.                         stcl_d(numberstring, jarl[killed].wealth);
  2265.                         strcat(saystring, " ");
  2266.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS, "golden marks"));
  2267.                         strcat(saystring, " ");
  2268.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FROM, "from"));
  2269.                         strcat(saystring, " ");
  2270.                         saywho(JARL, killed, FALSE, TRUE);
  2271.                         strcat(saystring, ".");
  2272.                         say(LOWER);
  2273.                         anykey();
  2274.                 }   }
  2275.                 else
  2276.                 {   for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  2277.                     {   if
  2278.                         (   jarl[whichjarl].alive
  2279.                          && jarl[whichjarl].hero == killerhero
  2280.                          && jarl[whichjarl].where == jarl[killed].where
  2281.                         )
  2282.                         {   assert(whichjarl != killed);
  2283.  
  2284.                             if (jarl[killed].wealth)
  2285.                             {   jarl[whichjarl].wealth += jarl[killed].wealth;
  2286.                                 saywho(JARL, whichjarl, FALSE, FALSE);
  2287.                                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES, "takes"));
  2288.                                 strcat(saystring, " ");
  2289.                                 stcl_d(numberstring, jarl[killed].wealth);
  2290.                                 strcat(saystring, " ");
  2291.                                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS, "golden marks"));
  2292.                                 strcat(saystring, " ");
  2293.                                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FROM, "from"));
  2294.                                 strcat(saystring, " ");
  2295.                                 saywho(JARL, killed, FALSE, TRUE);
  2296.                                 strcat(saystring, ".");
  2297.                                 say(LOWER);
  2298.                                 anykey();
  2299.             }   }   }   }   }
  2300.  
  2301.             if (killedhero != -1)
  2302.             {   if (hero[killedhero].control == HUMAN)
  2303.                 {   saywho(HERO, killedhero, TRUE, FALSE);
  2304.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_LOSE, "lose"));
  2305.                     strcat(saystring, " ");
  2306.                     stcl_d(numberstring, jarl[killed].strength / 2);
  2307.                     strcat(saystring, numberstring);
  2308.                     strcat(saystring, " (");
  2309.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_GLORY, "G"));
  2310.                     strcat(saystring, ")");
  2311.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_UNCHAR_GLORY, "lory"));
  2312.                     strcat(saystring, " ");
  2313.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_OR, "or"));
  2314.                     strcat(saystring, " ");
  2315.                     stcl_d(numberstring, jarl[killed].strength / 2);
  2316.                     strcat(saystring, numberstring);
  2317.                     strcat(saystring, " (");
  2318.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_LUCK, "L"));
  2319.                     strcat(saystring, ")");
  2320.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_UNCHAR_LUCK, "uck"));
  2321.                     strcat(saystring, "?");
  2322.                     say(LOWER);
  2323.                     do
  2324.                     {   result = getevent(KEYBOARD, NULL);
  2325.                     } while (result != onekey[ONEKEY_GLORY] && result != onekey[ONEKEY_LUCK]);
  2326.                     if (result == onekey[ONEKEY_GLORY])
  2327.                     {   hero[killedhero].glory -= jarl[killed].strength / 2;
  2328.                         if (hero[killedhero].glory < 0)
  2329.                         {   hero[killedhero].glory = 0;
  2330.                     }   }
  2331.                     else
  2332.                     {   // assert(result == onekey[ONEKEY_LUCK]);
  2333.                         hero[killedhero].luck  -= jarl[killed].strength / 2;
  2334.                         if (hero[killedhero].luck < 0)
  2335.                         {   hero[killedhero].luck = 0;
  2336.                 }   }   }
  2337.                 else
  2338.                 {   // assert(hero[killedhero].control == AMIGA);
  2339.                     hero[killedhero].glory -= jarl[killed].strength / 2;
  2340.                     if (hero[killedhero].glory < 0)
  2341.                     {   hero[killedhero].glory = 0;
  2342.             }   }   }
  2343.             if (killerhero != -1)
  2344.             {   gain(killerhero, jarl[killed].strength / 2, jarl[killed].strength / 2);
  2345.     }   }   }
  2346.     elif (killedtype == KINGDOM)
  2347.     {   world[killed].hero = killerhero;
  2348.         darken();
  2349.         saywho(HERO, killerhero, FALSE, FALSE);
  2350.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HAS_CONQUERED_KINGDOM, "has conquered kingdom"));
  2351.         strcat(saystring, " ");
  2352.         strcat(saystring, world[killed].name);
  2353.         strcat(saystring, " (");
  2354.         stcl_d(numberstring, world[killed].tax);
  2355.         strcat(saystring, numberstring);
  2356.         strcat(saystring, ").");
  2357.         say(LOWER);
  2358.         anykey();
  2359.     } elif (killedtype == MONSTER)
  2360.     {   monster[killed].alive = FALSE;
  2361.         remove_monster(killed, TRUE);
  2362.  
  2363.         strcpy(saystring, monstertypes[monster[killed].species]);
  2364.         strcat(saystring, " ");
  2365.         strcat(saystring, monster[killed].name);
  2366.         strcat(saystring, " ");
  2367.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_KILLED, "is killed"));
  2368.         strcat(saystring, "!");
  2369.         say(LOWER);
  2370.         anykey();
  2371.  
  2372.         for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  2373.         {   if
  2374.             (   treasure[whichtreasure].possessortype == MONSTER
  2375.              && treasure[whichtreasure].possessor == killed
  2376.             )
  2377.             {   // give the treasure to the killer of the dragon
  2378.                 // assert(monster[killed].species == DRAGON);
  2379.                 treasure[whichtreasure].possessortype = killertype;
  2380.                 treasure[whichtreasure].possessor     = killer;
  2381.                 treasure[whichtreasure].where         = -1;
  2382.  
  2383.                 saywho(killertype, killer, FALSE, FALSE);
  2384.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FINDS_THE, "finds the"));
  2385.                 strcat(saystring, " ");
  2386.                 strcat(saystring, treasure[whichtreasure].name);
  2387.                 strcat(saystring, ".");
  2388.                 say(LOWER);
  2389.                 anykey();
  2390.         }   }
  2391.  
  2392.         if (monster[killed].wealth > 0)
  2393.         {   hero[killerhero].wealth += monster[killed].wealth;
  2394.  
  2395.             saywho(killertype, killer, FALSE, FALSE);
  2396.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FINDS, "finds"));
  2397.             strcat(saystring, " ");
  2398.             stcl_d(numberstring, monster[killed].wealth);
  2399.             strcat(saystring, numberstring);
  2400.             strcat(saystring, " ");
  2401.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS, "golden marks"));
  2402.             strcat(saystring, ".");
  2403.             say(LOWER);
  2404.             anykey();
  2405.         }
  2406.  
  2407.         switch (monster[killed].species)
  2408.         {
  2409.         case DRAGON:
  2410.             glory = 6;
  2411.             luck  = 5;
  2412.         break;
  2413.         case DROW:
  2414.             glory = 3;
  2415.             luck  = 2;
  2416.         break;
  2417.         case GHOST:
  2418.             glory = 2;
  2419.             luck  = 2;
  2420.         break;
  2421.         case GIANT:
  2422.             glory = 4;
  2423.             luck  = 3;
  2424.         break;
  2425.         case TROLL:
  2426.             glory = 3;
  2427.             luck  = 3;
  2428.         break;
  2429.         case WITCH:
  2430.             glory = 5;
  2431.             luck  = 4;
  2432.         break;
  2433.         default:
  2434.             // assert(0);
  2435.         break;
  2436.         }
  2437.         // assert(killerhero != -1);
  2438.         gain(killerhero, glory, luck);
  2439.  
  2440.         // check if hero was present at the combat
  2441.         if
  2442.         (   killerhero != -1
  2443.          && hero[killerhero].attacking
  2444.         )
  2445.         {   if
  2446.             (   (   monster[killed].species == DROW
  2447.                  || monster[killed].species == GHOST
  2448.                  || monster[killed].species == WITCH
  2449.                 )
  2450.              && hero[killer].rune == -1
  2451.             )
  2452.             {   hero[killer].rune = rand() % (RUNES + 1);
  2453.                 saywho(HERO, killer, FALSE, FALSE);
  2454.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_LEARNS_THE_RUNE, "learns the rune"));
  2455.                 strcat(saystring, " ");
  2456.                 strcat(saystring, runename[hero[killer].rune]);
  2457.                 strcat(saystring, ", ");
  2458.                 strcat(saystring, runedesc[hero[killer].rune]);
  2459.                 strcat(saystring, ".");
  2460.                 say(LOWER);
  2461.                 anykey();
  2462. }   }   }   }
  2463.  
  2464. MODULE FLAG recruit(SLONG recruited, SLONG recruiterhero)
  2465. {   SLONG jarls = 0,
  2466.           result,
  2467.           whichjarl;
  2468.  
  2469.     if (jarl[recruited].hero == -1 && hero[recruiterhero].luck >= 1 && jarl[recruited].recruitable)
  2470.     {   jarl[recruited].recruitable = FALSE;
  2471.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  2472.         {   if (jarl[whichjarl].alive && jarl[whichjarl].hero == recruiterhero)
  2473.             {   jarls++;
  2474.         }   }
  2475.         if (jarls <= 3)
  2476.         {   if (hero[recruiterhero].control == HUMAN)
  2477.             {   saywho(HERO, recruiterhero, TRUE, FALSE);
  2478.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_RECRUIT_JARL, "recruit jarl"));
  2479.                 strcat(saystring, " ");
  2480.                 strcat(saystring, jarl[recruited].name);
  2481.                 strcat(saystring, " (");
  2482.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_YES, "Y"));
  2483.                 strcat(saystring, "/");
  2484.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_NO, "N"));
  2485.                 strcat(saystring, ")?");
  2486.                 say(LOWER);
  2487.                 do
  2488.                 {   result = getevent(KEYBOARD, NULL);
  2489.                 } while (result != onekey[ONEKEY_YES] && result != onekey[ONEKEY_NO]);
  2490.                 if (result == onekey[ONEKEY_YES])
  2491.                 {   hero[recruiterhero].luck--;
  2492.                     gain(recruiterhero, jarl[recruited].strength / 2, jarl[recruited].strength / 2);
  2493.                     jarl[recruited].hero = recruiterhero;
  2494.                     return(TRUE);
  2495.                 } else
  2496.                 {   // assert(result == onekey[ONEKEY_NO]);
  2497.             }   }
  2498.             else
  2499.             {   // assert(hero[recruiterhero].control == AMIGA);
  2500.                 hero[recruiterhero].luck--;
  2501.                 gain(recruiterhero, jarl[recruited].strength / 2, jarl[recruited].strength / 2);
  2502.                 jarl[recruited].hero = recruiterhero;
  2503.                 saywho(HERO, recruiterhero, FALSE, FALSE);
  2504.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_RECRUITS_JARL, "recruits jarl"));
  2505.                 strcat(saystring, " ");
  2506.                 strcat(saystring, jarl[recruited].name);
  2507.                 strcat(saystring, ".");
  2508.                 say(LOWER);
  2509.                 anykey();
  2510.                 return(TRUE);
  2511.     }   }   }
  2512.  
  2513.     return(FALSE);
  2514. }
  2515.  
  2516. MODULE SLONG d6(void)
  2517. {   return((rand() % 6) + 1);
  2518. }
  2519.  
  2520. AGLOBAL void cleanexit(SLONG rc)
  2521. {   BPTR  FileHandle /* = NULL */ ;
  2522.     SLONG whichhero;
  2523.  
  2524.     destroycounters();
  2525.  
  2526.     if (ASLRqPtr)
  2527.     {   FreeAslRequest(ASLRqPtr);
  2528.         ASLRqPtr = NULL;
  2529.     }
  2530.     if (OldWindowPtr)
  2531.     {   ProcessPtr->pr_WindowPtr = OldWindowPtr;
  2532.     }
  2533.  
  2534.     /* It does not matter whether there are outstanding messages for a
  2535.     window when it is closed, provided that the window does not use a
  2536.     shared IDCMP message port. */
  2537.  
  2538.     if (HelpWindowPtr)
  2539.     {   CloseWindow(HelpWindowPtr);
  2540.         HelpWindowPtr = NULL;
  2541.     }
  2542.     if (MainWindowPtr)
  2543.     {   ClearMenuStrip(MainWindowPtr);
  2544.         CloseWindow(MainWindowPtr);
  2545.         MainWindowPtr = NULL;
  2546.     }
  2547.     if (GListPtr)
  2548.     {   FreeGadgets(GListPtr);
  2549.         GListPtr = NULL;
  2550.     }
  2551.     if (MenuPtr)
  2552.     {   FreeMenus(MenuPtr);
  2553.         MenuPtr = NULL;
  2554.     }
  2555.     if (VisualInfoPtr)
  2556.     {   FreeVisualInfo(VisualInfoPtr);
  2557.         VisualInfoPtr = NULL;
  2558.     }
  2559.     if (ScreenPtr)
  2560.     {   CloseScreen(ScreenPtr);
  2561.         ScreenPtr = NULL;
  2562.     }
  2563.     if (ASLBase)
  2564.     {   CloseLibrary((struct Library *) ASLBase);
  2565.         ASLBase = NULL;
  2566.     }
  2567.     if (GadToolsBase)
  2568.     {   CloseLibrary((struct Library *) GadToolsBase);
  2569.         GadToolsBase = NULL;
  2570.     }
  2571.     if (GfxBase)
  2572.     {   CloseLibrary((struct Library *) GfxBase);
  2573.         GfxBase = NULL;
  2574.     }
  2575.     if (LocaleBase)
  2576.     {   CloseCatalog(li.li_Catalog);
  2577.         CloseLibrary((struct Library *) LocaleBase);
  2578.         LocaleBase = NULL;
  2579.     }
  2580.     if (IntuitionBase)
  2581.     {   OpenWorkBench();
  2582.         CloseLibrary((struct Library *) IntuitionBase);
  2583.         IntuitionBase = NULL;
  2584.     }
  2585.     if (ArgsPtr)
  2586.     {   FreeArgs(ArgsPtr);
  2587.         ArgsPtr = NULL;
  2588.     }
  2589.  
  2590.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  2591.     {    IOBuffer[whichhero] = (SBYTE) hero[whichhero].control;
  2592.     }
  2593.     IOBuffer[ 6] = (UBYTE)   (DisplayID     / 16777216);
  2594.     IOBuffer[ 7] = (UBYTE)  ((DisplayID     % 16777216) / 65536);
  2595.     IOBuffer[ 8] = (UBYTE) (((DisplayID     % 16777216) % 65536) / 256);
  2596.     IOBuffer[ 9] = (UBYTE) (((DisplayID     % 16777216) % 65536) % 256);
  2597.     IOBuffer[10] = (UBYTE)   (DisplayWidth  / 16777216);
  2598.     IOBuffer[11] = (UBYTE)  ((DisplayWidth  % 16777216) / 65536);
  2599.     IOBuffer[12] = (UBYTE) (((DisplayWidth  % 16777216) % 65536) / 256);
  2600.     IOBuffer[13] = (UBYTE) (((DisplayWidth  % 16777216) % 65536) % 256);
  2601.     IOBuffer[14] = (UBYTE)   (DisplayHeight / 16777216);
  2602.     IOBuffer[15] = (UBYTE)  ((DisplayHeight % 16777216) / 65536);
  2603.     IOBuffer[16] = (UBYTE) (((DisplayHeight % 16777216) % 65536) / 256);
  2604.     IOBuffer[17] = (UBYTE) (((DisplayHeight % 16777216) % 65536) % 256);
  2605.     IOBuffer[18] = (UBYTE)   (DisplayDepth  / 65536);
  2606.     IOBuffer[19] = (UBYTE)   (DisplayDepth  % 65536);
  2607.     IOBuffer[20] = (UBYTE)    speed;
  2608.     if (FileHandle = Open("PROGDIR:Saga.config", MODE_NEWFILE))
  2609.     {   Write(FileHandle, IOBuffer, 21);
  2610.         Close(FileHandle);
  2611.         // FileHandle = NULL;
  2612.     }
  2613.  
  2614.     exit(rc); // End of program.
  2615. }
  2616.  
  2617. MODULE void say(SLONG position)
  2618. {   SLONG length;
  2619.  
  2620.     length = strlen(saystring);
  2621.  
  2622.     SetAPen(MainWindowPtr->RPort, BLACK);
  2623.     if (position == UPPER)
  2624.     {   RectFill
  2625.         (   MainWindowPtr->RPort,
  2626.             0,   MESSAGEY,
  2627.             639, MESSAGEY + 7
  2628.         );
  2629.         Move(MainWindowPtr->RPort, 4, MESSAGEY + 6);
  2630.     }
  2631.     else
  2632.     {   // assert(position == LOWER);
  2633.         RectFill
  2634.         (   MainWindowPtr->RPort,
  2635.             0,   MESSAGEY + 10,
  2636.             639, MESSAGEY + 27
  2637.         );
  2638.         Move(MainWindowPtr->RPort, 4, MESSAGEY + 16);
  2639.     }
  2640.  
  2641.     SetAPen(MainWindowPtr->RPort, WHITE);
  2642.     if (position == LOWER && length > 79)
  2643.     {   Text(MainWindowPtr->RPort, saystring, 79);
  2644.         Move(MainWindowPtr->RPort, 4, MESSAGEY + 26);
  2645.         Text(MainWindowPtr->RPort, &saystring[79], length - 79);
  2646.     } else
  2647.     {   Text(MainWindowPtr->RPort, saystring, length);
  2648. }   }
  2649.  
  2650. MODULE void newhero(SLONG whichhero, FLAG givesord)
  2651. {   SLONG whichjarl, whichsord;
  2652.  
  2653.     hero[whichhero].where     =
  2654.     hero[whichhero].homewhere = rand() % 36;
  2655.     hero[whichhero].glory     =
  2656.     hero[whichhero].wealth    = 0;
  2657.     hero[whichhero].luck      = 3;
  2658.     hero[whichhero].alive     = TRUE;
  2659.     hero[whichhero].verydead  =
  2660.     hero[whichhero].wounded   =
  2661.     hero[whichhero].hagall    =
  2662.     hero[whichhero].loseturn  = FALSE;
  2663.     hero[whichhero].rune      =
  2664.     hero[whichhero].god       = -1;
  2665.     hero[whichhero].sea       = NORMAL;
  2666.     hero[whichhero].maidens   = 0;
  2667.     if (givesord)
  2668.     {   hero[whichhero].promoted = -1;
  2669.     }
  2670.  
  2671.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  2672.     {   if (jarl[whichjarl].hero == whichhero)
  2673.         {   jarl[whichjarl].hero = -1;
  2674.     }   }
  2675.  
  2676.     deselect_hero(whichhero, FALSE);
  2677.     move_hero(whichhero, TRUE);
  2678.     // we don't unslot newborn counters
  2679.  
  2680.     if (!givesord)
  2681.     {   return;
  2682.     }
  2683.     
  2684.     // at least one sword should should always be available
  2685.     do
  2686.     {   whichsord = rand() % 6;
  2687.     } while (sord[whichsord].taken);
  2688.     sord[whichsord].taken         = TRUE;
  2689.     sord[whichsord].possessortype = HERO;
  2690.     sord[whichsord].possessor     = whichhero;
  2691.     sord[whichsord].where         = -1;
  2692. }
  2693.  
  2694. MODULE SLONG getevent(SLONG mode, SLONG* countertype)
  2695. {   AUTO    UWORD                code,
  2696.                                  qual;
  2697.     AUTO    ULONG                class;
  2698.     AUTO    struct IntuiMessage* MsgPtr;
  2699.     AUTO    LONG                 country;
  2700.     AUTO    SLONG                counter,
  2701.                                  ticks = 0;
  2702.     AUTO    WORD                 mousex, mousey;
  2703.     AUTO    struct MenuItem*     ItemPtr;
  2704.     PERSIST SLONG                cheat = 0;
  2705.  
  2706.     /* return codes:
  2707.     -4: Escape
  2708.     -3: spacebar
  2709.     -2: backspace
  2710.     -1: invalid country */
  2711.  
  2712.     while(1)
  2713.     {   while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
  2714.         {   class  = MsgPtr->Class;
  2715.             code   = MsgPtr->Code;
  2716.             mousex = MsgPtr->MouseX;
  2717.             mousey = MsgPtr->MouseY;
  2718.             qual   = MsgPtr->Qualifier;
  2719.             if (class == IDCMP_MENUVERIFY && code == MENUHOT && mousey >= 0)
  2720.             {   code = MENUCANCEL;
  2721.                 ReplyMsg(MsgPtr);
  2722.             } else
  2723.             {   GT_ReplyIMsg(MsgPtr); // seems that this doesn't work for menu verify messages
  2724.             }
  2725.             switch(class)
  2726.             {
  2727.             case IDCMP_CLOSEWINDOW:
  2728.                 cleanexit(EXIT_SUCCESS);
  2729.             break;
  2730.             case IDCMP_REFRESHWINDOW:
  2731.                 GT_BeginRefresh(MainWindowPtr);
  2732.                 GT_EndRefresh(MainWindowPtr, TRUE);
  2733.             break;
  2734.             case IDCMP_MOUSEBUTTONS:
  2735.                 if ((code == MIDDLEDOWN || code == MENUUP) && !(qual & IEQUALIFIER_REPEAT))
  2736.                 {   if (mode == KEYBOARD)
  2737.                     {   return('0');
  2738.                     } elif (mode != ANYKEY || tickwait == -1)
  2739.                     {   return(-3);
  2740.                 }   }
  2741.                 elif (code == SELECTDOWN && !(qual & IEQUALIFIER_REPEAT))
  2742.                 {   if (mode == KEYBOARD || (mode == ANYKEY && tickwait == -1))
  2743.                     {   if (mousey >= MESSAGEY)
  2744.                         {   return('0');
  2745.                         } else
  2746.                         {   return(-1);
  2747.                     }   }
  2748.                     elif (mode == COUNTER)
  2749.                     {   if (mousey >= MESSAGEY)
  2750.                         {   return(-3);
  2751.                         }
  2752.                         counter = checkcounters(mousex, mousey, countertype);
  2753.                         if (counter == -1)
  2754.                         {   country = checkcountry(mousex, mousey);
  2755.                             *(countertype) = KINGDOM;
  2756.                             flash(country);
  2757.                             return(country);
  2758.                         } else
  2759.                         {   return(counter);
  2760.                     }   }
  2761.                     elif (mode == COUNTRY)
  2762.                     {   if (mousey >= MESSAGEY)
  2763.                         {   return(-3);
  2764.                         }
  2765.                         counter = checkcounters(mousex, mousey, countertype);
  2766.                         if (counter == -1)
  2767.                         {   country = checkcountry(mousex, mousey);
  2768.                             *(countertype) = KINGDOM;
  2769.                             flash(country);
  2770.                             return(country);
  2771.                         } else
  2772.                         {   if (*(countertype) == HERO)
  2773.                             {   flash(hero[counter].where);
  2774.                                 return(hero[counter].where);
  2775.                             } elif (*(countertype) == JARL)
  2776.                             {   flash(jarl[counter].where);
  2777.                                 return(jarl[counter].where);
  2778.                             } elif (*(countertype) == MONSTER)
  2779.                             {   flash(monster[counter].where);
  2780.                                 return(monster[counter].where);
  2781.                 }   }   }   }
  2782.             break;
  2783.             case IDCMP_INTUITICKS:
  2784.                 if (mode == ANYKEY && tickwait != -1)
  2785.                 {   ticks++;
  2786.                     if (ticks >= tickwait)
  2787.                     {   return(-3);
  2788.                 }   }
  2789.                 counter = checkcounters(mousex, mousey, countertype);
  2790.                 if (counter == -1)
  2791.                 {   country = checkcountry(mousex, mousey);
  2792.                     *(countertype) = KINGDOM;
  2793.                     showcountry(country);
  2794.                 } else
  2795.                 {   if (*(countertype) == HERO)
  2796.                     {   saywho(HERO, counter, FALSE, FALSE);
  2797.                         strcat(saystring, "(");
  2798.                         stcl_d(numberstring, hero[counter].strength);
  2799.                         strcat(saystring, numberstring);
  2800.                         strcat(saystring, "-");
  2801.                         stcl_d(numberstring, hero[counter].moves);
  2802.                         strcat(saystring, numberstring);
  2803.                         strcat(saystring, ")");
  2804.                         say(UPPER);
  2805.                     } elif (*(countertype) == JARL)
  2806.                     {   if (jarl[counter].face == FACEDOWN)
  2807.                         {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_UNKNOWN_JARL, "Unknown jarl"));
  2808.                             strcat(saystring, " (?-?)");
  2809.                         } else
  2810.                         {   saywho(JARL, counter, FALSE, FALSE);
  2811.                             strcat(saystring, "(");
  2812.                             stcl_d(numberstring, jarl[counter].strength);
  2813.                             strcat(saystring, numberstring);
  2814.                             strcat(saystring, "-");
  2815.                             stcl_d(numberstring, jarl[counter].moves);
  2816.                             strcat(saystring, numberstring);
  2817.                             strcat(saystring, ")");
  2818.                         }
  2819.                         say(UPPER);
  2820.                     } elif (*(countertype) == MONSTER)
  2821.                     {   strcpy(saystring, monstertypes[monster[counter].species]);
  2822.                         strcat(saystring, " ");
  2823.                         strcat(saystring, monster[counter].name);
  2824.                         strcat(saystring, " (");
  2825.                         stcl_d(numberstring, monster[counter].strength);
  2826.                         strcat(saystring, numberstring);
  2827.                         strcat(saystring, "-");
  2828.                         stcl_d(numberstring, monster[counter].moves);
  2829.                         strcat(saystring, numberstring);
  2830.                         strcat(saystring, ")");
  2831.                         say(UPPER);
  2832.                     } elif (*(countertype) == TREASURE)
  2833.                     {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_THE, "The"));
  2834.                         strcat(saystring, " ");
  2835.                         strcat(saystring, treasure[counter].name);
  2836.                         strcat(saystring, " ");
  2837.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TREASURE2, "treasure"));
  2838.                         say(UPPER);
  2839.                     } elif (*(countertype) == SORD)
  2840.                     {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_SWORD, "Sword"));
  2841.                         strcat(saystring, " ");
  2842.                         strcat(saystring, sord[counter].name);
  2843.                         say(UPPER);
  2844.                 }   }
  2845.             break;
  2846.             case IDCMP_VANILLAKEY:
  2847.                 if (code == ' ' && (mode != ANYKEY || tickwait == -1))
  2848.                 {   return(-3);
  2849.                 } elif (code == 27) // Escape
  2850.                 {   if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  2851.                     {   cleanexit(EXIT_SUCCESS);
  2852.                     } elif (mode != ANYKEY || tickwait == -1)
  2853.                     {   return(-4);
  2854.                 }   }
  2855.                 elif (mode == KEYBOARD || (mode == ANYKEY && tickwait == -1))
  2856.                 {   code = toupper(code);
  2857.                     return((SLONG) code);
  2858.                 }
  2859.                 elif (code == 8) // backspace
  2860.                 {   if (mode != ANYKEY || tickwait == -1)
  2861.                     {   return(-2);
  2862.                 }   }
  2863.             break;
  2864.             case IDCMP_RAWKEY:
  2865.                 switch(code)
  2866.                 {
  2867.                 case HELP:
  2868.                     if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  2869.                     {   summarywindow();
  2870.                     } else
  2871.                     {   counter = checkcounters(mousex, mousey, countertype);
  2872.                         if (counter == -1)
  2873.                         {   country = checkcountry(mousex, mousey);
  2874.                             if (country >= 0)
  2875.                             {   infowindow(KINGDOM, country);
  2876.                             } else
  2877.                             {   summarywindow();
  2878.                         }   }
  2879.                         else
  2880.                         {   infowindow(*(countertype), counter);
  2881.                     }   }
  2882.                 break;
  2883.                 default:
  2884.                     if
  2885.                     (   (mode == KEYBOARD || (mode == ANYKEY && tickwait == -1))
  2886.                      && code < KEYUP && (code < FIRSTQUALIFIER || code > LASTQUALIFIER)
  2887.                     )
  2888.                     {   if (code == SCAN_F1 + cheat)
  2889.                         {   cheat++;
  2890.                             if (cheat == 5)
  2891.                             {   cheat = 0;
  2892.                                 hero[BEOWULF].luck = 5000;
  2893.                                 DisplayBeep(ScreenPtr);
  2894.                         }   }
  2895.                         else cheat = 0;
  2896.                     }
  2897.                 break;
  2898.                 }
  2899.             break;
  2900.             case IDCMP_MENUPICK:
  2901.                 while (code != MENUNULL)
  2902.                 {   ItemPtr = ItemAddress(MenuPtr, code);
  2903.  
  2904.                     switch (MENUNUM(code))
  2905.                     {
  2906.                     case MN_PROJECT:
  2907.                         switch (ITEMNUM(code))
  2908.                         {
  2909.                         case IN_NEW:
  2910.                             return(-4);
  2911.                         case IN_SAVE:
  2912.                             savegame(FALSE);
  2913.                         break;
  2914.                         case IN_SAVEAS:
  2915.                             savegame(TRUE);
  2916.                         break;
  2917.                         case IN_QUIT:
  2918.                             cleanexit(EXIT_SUCCESS);
  2919.                         break;
  2920.                         default:
  2921.                             // IN_OPEN
  2922.                         break;
  2923.                         }
  2924.                     break;
  2925.                     case MN_HELP:
  2926.                         switch(ITEMNUM(code))
  2927.                         {
  2928.                         case IN_GAME_SUMMARY:
  2929.                             summarywindow();
  2930.                         break;
  2931.                         case IN_ABOUT:
  2932.                             helpabout();
  2933.                         break;
  2934.                         default:
  2935.                         break;
  2936.                         }
  2937.                     break;
  2938.                     default:
  2939.                     break;
  2940.                     }
  2941.                     code = ItemPtr->NextSelect;
  2942.                 }
  2943.             break;
  2944.             default:
  2945.             break;
  2946. }   }   }   }
  2947.  
  2948. MODULE void showcountry(SLONG country)
  2949. {   if (country >= 0 && country <= 65)
  2950.     {   strcpy(saystring, world[country].name);
  2951.         if (country <= 35)
  2952.         {   strcat(saystring, " (");
  2953.             stcl_d(numberstring, world[country].tax);
  2954.             strcat(saystring, numberstring);
  2955.             strcat(saystring, ")");
  2956.     }   }
  2957.     else
  2958.     {   strcpy(saystring, "-");
  2959.     }
  2960.     say(UPPER);
  2961. }
  2962.  
  2963. MODULE void phase1(void)
  2964. {   SLONG besthero = -1,
  2965.           glory,
  2966.           whichhero,
  2967.           whichjarl,
  2968.           whichmonster,
  2969.           whichorder;
  2970.     FLAG  done;
  2971.  
  2972.    /* "1. MOVEMENT. All heroes and jarls move. The hero with the most
  2973.         glory and his or her jarls move first. In cases of ties the heroes
  2974.         roll dice to see who goes first, with the highest roll going
  2975.         first.
  2976.  
  2977.         A counter may move as many areas as its movement factor. Each area
  2978.         is defined by colour or, in the case of sea areas, by dividing
  2979.         lines. Counters may move and remain in sea areas just as if they
  2980.         were on land. There is no difference between land movement and sea
  2981.         movement." */
  2982.  
  2983.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  2984.     {   hero[whichhero].moved  =
  2985.         hero[whichhero].hagall =
  2986.         hero[whichhero].routed = FALSE;
  2987.     }
  2988.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  2989.     {   jarl[whichjarl].hagall =
  2990.         jarl[whichjarl].routed = FALSE;
  2991.     }
  2992.     for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  2993.     {   monster[whichmonster].hagall = FALSE;
  2994.     }
  2995.  
  2996.     for (whichorder = 0; whichorder <= HEROES; whichorder++)
  2997.     {   glory = -1;
  2998.         done = TRUE;
  2999.         for (whichhero = 0; whichhero <= HEROES; whichhero++)
  3000.         {   if (hero[whichhero].alive && !hero[whichhero].moved)
  3001.             {   done = FALSE;
  3002.                 if
  3003.                 (   hero[whichhero].glory > glory
  3004.                  || (hero[whichhero].glory == glory && !(rand() % 2))
  3005.                 )
  3006.                 {   besthero = whichhero;
  3007.                     glory    = hero[whichhero].glory;
  3008.         }   }   }
  3009.         if (done)
  3010.         {   order[whichorder] = -1;
  3011.         } else
  3012.         {   order[whichorder] = besthero;
  3013.             hero[besthero].moved = TRUE;
  3014.     }   }
  3015.  
  3016.     for (whichorder = 0; whichorder <= HEROES; whichorder++)
  3017.     {   if (order[whichorder] == -1)
  3018.         {   break;
  3019.         } else
  3020.         {   move(order[whichorder]);
  3021.     }   }
  3022.  
  3023.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  3024.     {   hero[whichhero].sea      = NORMAL;
  3025.         hero[whichhero].loseturn = FALSE;
  3026.     }
  3027.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3028.     {   jarl[whichjarl].sea      = NORMAL;
  3029.         jarl[whichjarl].loseturn = FALSE;
  3030.     }
  3031.     for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  3032.     {   monster[whichmonster].sea      = NORMAL;
  3033. }   }
  3034.  
  3035. MODULE void phase2(void)
  3036. {   SLONG whichorder;
  3037.  
  3038.     /* "2. COMBAT AND JARLS. Combat occurs in the same sequence as
  3039.         movement; jarls are recruited after combat.
  3040.  
  3041.         Heroes *must* attack at least one monster (if there is a monster)
  3042.         in the area they are in during the combat portion of the turn. If
  3043.         there is more than one monster they may choose which one they wish
  3044.         to fight. They may attack more than one monster in an area." */
  3045.  
  3046.     for (whichorder = 0; whichorder <= HEROES; whichorder++)
  3047.     {   if (order[whichorder] == -1)
  3048.         {   break;
  3049.         } else
  3050.         {   attack(order[whichorder]);
  3051. }   }   }
  3052.  
  3053. MODULE void attack(SLONG whichhero)
  3054. {   SLONG attackers,
  3055.           countertype = -1,
  3056.           country     = -1,
  3057.           totalstrength,
  3058.           weakestmonster,
  3059.           weakeststrength,
  3060.           whichattack,
  3061.           whichcountry,
  3062.           whichjarl,
  3063.           whichmonster,
  3064.           whichmonster2,
  3065.           whichrivalhero;
  3066.     FLAG  must        = FALSE;
  3067.  
  3068.     if (hero[whichhero].alive)
  3069.     {   for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  3070.         {   hero[whichhero].attacked[whichattack]   = -1;
  3071.             hero[whichhero].attacktype[whichattack] = -1;
  3072.         }
  3073.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3074.         {   if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
  3075.             {   for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  3076.                 {   jarl[whichjarl].attacked[whichattack]   = -1;
  3077.                     jarl[whichjarl].attacktype[whichattack] = -1;
  3078.         }   }   }
  3079.  
  3080.         for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  3081.         {   if (monster[whichmonster].alive && monster[whichmonster].where == hero[whichhero].where)
  3082.             {   must = TRUE;
  3083.                 weakeststrength = 99;
  3084.                 for (whichmonster2 = 0; whichmonster2 <= MONSTERS; whichmonster2++)
  3085.                 {   if (monster[whichmonster2].alive && monster[whichmonster2].where == hero[whichhero].where && monster[whichmonster2].strength < weakeststrength)
  3086.                     {   weakeststrength = monster[whichmonster2].strength;
  3087.                         weakestmonster  = whichmonster2;
  3088.                 }   }
  3089.                 break;
  3090.         }   }
  3091.  
  3092.         if (hero[whichhero].control == HUMAN)
  3093.         {   while(1)
  3094.             {   saywho(HERO, whichhero, TRUE, FALSE);
  3095.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_SELECT_ATTACKERS, "select attackers"));
  3096.                 strcat(saystring, "?");
  3097.                 say(LOWER);
  3098.                 country = getevent(COUNTRY, &countertype);
  3099.  
  3100.                 if (country >= 0)
  3101.                 {   if (hero[whichhero].alive && hero[whichhero].where == country && !hero[whichhero].routed)
  3102.                     {   attackers = 1;
  3103.                         select_hero(whichhero, FALSE);
  3104.                         hero[whichhero].attacking = TRUE;
  3105.                     } else
  3106.                     {   attackers = 0;
  3107.                     }
  3108.                     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3109.                     {   if (jarl[whichjarl].alive && jarl[whichjarl].where == country && !jarl[whichjarl].routed && jarl[whichjarl].hero == whichhero)
  3110.                         {   attackers++;
  3111.                             select_jarl(whichjarl, FALSE);
  3112.                             jarl[whichjarl].attacking = TRUE;
  3113.                     }   }
  3114.                     if (attackers)
  3115.                     {   refreshcounters();
  3116.                         getdefender(whichhero, country);
  3117.                 }   }
  3118.                 elif (country == -3)
  3119.                 {   if (must && hero[whichhero].alive && !hero[whichhero].routed)
  3120.                     {   // check whether the hero has fought a monster
  3121.                         for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  3122.                         {   if (hero[whichhero].attacktype[whichattack] == MONSTER)
  3123.                             {   return;
  3124.                         }   }
  3125.                         saywho(HERO, whichhero, TRUE, FALSE);
  3126.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_YOU_MUST_FIGHT_A_MONSTER, "you must fight a monster"));
  3127.                         strcat(saystring, ".");
  3128.                         say(LOWER);
  3129.                         anykey();
  3130.                     } else
  3131.                     {   if (hero[whichhero].attacking)
  3132.                         {   deselect_hero(whichhero, FALSE);
  3133.                         }
  3134.                         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3135.                         {   if (jarl[whichjarl].alive && jarl[whichjarl].attacking)
  3136.                             {   deselect_jarl(whichjarl, FALSE);
  3137.                         }   }
  3138.                         refreshcounters();
  3139.                         return;
  3140.         }   }   }   }
  3141.         elif (hero[whichhero].control == AMIGA)
  3142.         {   for (whichcountry = 0; whichcountry <= 65; whichcountry++)
  3143.             {   // check for possible enemies
  3144.  
  3145.                 if (!(totalstrength = getattackers(whichhero, whichcountry)))
  3146.                 {   continue;
  3147.                 }
  3148.                 for (whichrivalhero = 0; whichrivalhero <= HEROES; whichrivalhero++)
  3149.                 {   if (whichhero != whichrivalhero && hero[whichrivalhero].alive && hero[whichrivalhero].where == whichcountry && totalstrength > hero[whichhero].strength + 3)
  3150.                     {   amiga_attack(whichhero, HERO, whichrivalhero);
  3151.                 }   }
  3152.  
  3153.                 if (!(totalstrength = getattackers(whichhero, whichcountry)))
  3154.                 {   continue;
  3155.                 }
  3156.                 for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3157.                 {   if (jarl[whichjarl].alive && jarl[whichjarl].hero != whichhero && jarl[whichjarl].where == whichcountry && (jarl[whichjarl].face == FACEDOWN || totalstrength > jarl[whichjarl].strength + 3))
  3158.                     {    amiga_attack(whichhero, JARL, whichjarl);
  3159.                 }   }
  3160.  
  3161.                 if (!(totalstrength = getattackers(whichhero, whichcountry)))
  3162.                 {   continue;
  3163.                 }
  3164.                 for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  3165.                 {   if
  3166.                     (   monster[whichmonster].alive
  3167.                      && monster[whichmonster].where == whichcountry
  3168.                      && (   (must && weakestmonster == whichmonster)
  3169.                          || totalstrength > monster[whichmonster].strength + 1
  3170.                     )   )
  3171.                     {   amiga_attack(whichhero, MONSTER, whichmonster);
  3172.                 }   }
  3173.  
  3174.                 if (!(totalstrength = getattackers(whichhero, whichcountry)))
  3175.                 {   continue;
  3176.                 }
  3177.                 if (whichcountry <= 35 && world[whichcountry].hero != whichhero && !world[whichcountry].is && totalstrength > world[whichcountry].tax + 2)
  3178.                 {   amiga_attack(whichhero, KINGDOM, whichcountry);
  3179. }   }   }   }   }
  3180.  
  3181. MODULE void newgame(void)
  3182. {   SLONG whichhero, whichjarl, whichmonster, whichcountry, whichslot,
  3183.           whichtreasure, whichsord;
  3184.  
  3185.     OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_NEW,    NOSUB));
  3186.     OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_OPEN,   NOSUB));
  3187.     OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVE,   NOSUB));
  3188.     OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVEAS, NOSUB));
  3189.      OnMenu(MainWindowPtr, FULLMENUNUM(MN_HELP,    IN_GAME_SUMMARY, NOSUB));
  3190.  
  3191.     pathname[0] = 0;
  3192.  
  3193.     /* 0. SET UP
  3194.  
  3195.     "Divide the counters into four piles, keeping the heroes separate.
  3196.     The four piles, all face down, should be: monsters of all sorts,
  3197.     jarls, magic weapons [(swords)], and magic treasures.
  3198.  
  3199.     Each player picks a hero counter to represent him or her in the game.
  3200.     Players roll dice if two or more people want the same counter, and
  3201.     high roll chooses first." */
  3202.  
  3203.     reset_images();
  3204.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  3205.     {   hero[whichhero].strength  = HERO_STRENGTH;
  3206.         hero[whichhero].moves     = HERO_MOVES;
  3207.         hero[whichhero].name      = trueheroname[whichhero];
  3208.         hero[whichhero].attacking =
  3209.         hero[whichhero].defending =
  3210.         hero[whichhero].alive     = FALSE;
  3211.         hero[whichhero].verydead  = TRUE;
  3212.         hero[whichhero].glory     =
  3213.         hero[whichhero].luck      =
  3214.         hero[whichhero].wealth    = 0;
  3215.         hero[whichhero].rune      = -1;
  3216.         remove_hero(whichhero, FALSE);
  3217.     }
  3218.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3219.     {   jarl[whichjarl].hero      = -1;
  3220.         jarl[whichjarl].wealth    = 0;
  3221.         jarl[whichjarl].attacking =
  3222.         jarl[whichjarl].defending =
  3223.         jarl[whichjarl].alive     =
  3224.         jarl[whichjarl].taken     = FALSE;
  3225.         remove_jarl(whichjarl, FALSE);
  3226.     }
  3227.     for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  3228.     {   monster[whichmonster].alive = FALSE;
  3229.         monster[whichmonster].taken = FALSE;
  3230.         remove_monster(whichmonster, FALSE);
  3231.     }
  3232.     for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  3233.     {   remove_treasure(whichtreasure, FALSE);
  3234.         treasure[whichtreasure].taken         = FALSE;
  3235.         treasure[whichtreasure].possessor     =
  3236.         treasure[whichtreasure].possessortype =
  3237.         treasure[whichtreasure].where         = -1;
  3238.     }
  3239.     for (whichsord = 0; whichsord <= SORDS; whichsord++)
  3240.     {   remove_sord(whichsord, FALSE);
  3241.         sord[whichsord].taken         = FALSE;
  3242.         sord[whichsord].possessor     =
  3243.         sord[whichsord].possessortype =
  3244.         sord[whichsord].where         = -1;
  3245.     }
  3246.  
  3247.     for (whichcountry = 0; whichcountry <= 65; whichcountry++)
  3248.     {   world[whichcountry].hero = -1;
  3249.         world[whichcountry].is   = FALSE;
  3250.         for (whichslot = 0; whichslot <= SLOTS; whichslot++)
  3251.         {   world[whichcountry].slot[whichslot] = FALSE;
  3252.     }   }
  3253.  
  3254.     SetAPen(MainWindowPtr->RPort, BLACK);
  3255.     RectFill(MainWindowPtr->RPort, 0, 0, SCREENXPIXEL, SCREENYPIXEL);
  3256.     darken();
  3257.     drawmap();
  3258.  
  3259.     /* "Each player then picks a magic sword at random from the face-down
  3260.     pile. Magic swords will not be given out again in the game and so all
  3261.     of the left-over magic swords are put aside until the next game." */
  3262.  
  3263.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  3264.     {   if (hero[whichhero].control != NONE)
  3265.         {   /* "Heroes begin the game in a randomly determined area (found in the
  3266.             same manner as monsters are placed). This area should be noted on the
  3267.             record sheet, as it is sometimes necessary to know a hero's home
  3268.             country." */
  3269.             newhero(whichhero, TRUE);
  3270.     }   }
  3271.  
  3272.     place_monsters();
  3273.     place_jarls();
  3274.     refreshcounters();
  3275.  
  3276.     turn = 1;
  3277.     faxirides = 3;
  3278. }
  3279.  
  3280. MODULE void clearkybd(void)
  3281. {   struct IntuiMessage* MsgPtr;
  3282.  
  3283.     while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
  3284.         GT_ReplyIMsg(MsgPtr);
  3285. }
  3286.  
  3287. MODULE void titlescreen(void)
  3288. {   AUTO    FLAG                 done;
  3289.     AUTO    SLONG                whichhero;
  3290.     AUTO    struct IntuiMessage* MsgPtr;
  3291.     AUTO    ULONG                class;
  3292.     AUTO    UWORD                code, qual;
  3293.     AUTO    struct Gadget*       addr;
  3294.     AUTO    struct MenuItem*     ItemPtr;
  3295.  
  3296.     loaded   =
  3297.     gameover = FALSE;
  3298.  
  3299.      OnMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_NEW,    NOSUB));
  3300.      OnMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_OPEN,   NOSUB));
  3301.     OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVE,   NOSUB));
  3302.     OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVEAS, NOSUB));
  3303.     OffMenu(MainWindowPtr, FULLMENUNUM(MN_HELP,    IN_GAME_SUMMARY, NOSUB));
  3304.  
  3305.     SetAPen(MainWindowPtr->RPort, BLACK);
  3306.     RectFill(MainWindowPtr->RPort, 0, 0, SCREENXPIXEL, SCREENYPIXEL);
  3307.     drawlogo();
  3308.  
  3309.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  3310.     {   GT_SetGadgetAttrs(CycleGadgetPtr[whichhero], MainWindowPtr, NULL, GA_Disabled, FALSE, TAG_DONE);
  3311.     }
  3312.     GT_SetGadgetAttrs(SpeedGadgetPtr, MainWindowPtr, NULL, GA_Disabled, FALSE, TAG_DONE);
  3313.     RefreshGadgets(SpeedGadgetPtr, MainWindowPtr, NULL);
  3314.     if (speed == 2)
  3315.     {   GT_SetGadgetAttrs(SpeedGadgetPtr, MainWindowPtr, NULL, GTSL_Level, 0, TAG_DONE); // kludgy
  3316.     } else
  3317.     {   GT_SetGadgetAttrs(SpeedGadgetPtr, MainWindowPtr, NULL, GTSL_Level, 4 - speed, TAG_DONE); // kludgy
  3318.     }
  3319.     GT_SetGadgetAttrs(SpeedGadgetPtr, MainWindowPtr, NULL, GTSL_Level, speed, TAG_DONE); // kludgy
  3320.  
  3321.     SetAPen(MainWindowPtr->RPort, WHITE);
  3322.     SetDrMd(MainWindowPtr->RPort, JAM1);
  3323.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  3324.     {   Move(MainWindowPtr->RPort, 212, 208 + (whichhero * 16)    );
  3325.         Text(MainWindowPtr->RPort, cycleheroname[whichhero], 10);
  3326.         Move(MainWindowPtr->RPort, 212 + (cycleheropos[whichhero] * 8), 208 + (whichhero * 16) + 1);
  3327.         Text(MainWindowPtr->RPort, "_", 1);
  3328.     }
  3329.     if (cliload)
  3330.     {   if (loadgame(FALSE))
  3331.         {   loaded = TRUE;
  3332.         } else
  3333.         {   cliload = FALSE;
  3334.     }   }
  3335.  
  3336.     if (!cliload)
  3337.     {   done = FALSE;
  3338.         do
  3339.         {   while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
  3340.             {   addr  = (struct Gadget *) MsgPtr->IAddress;
  3341.                 class = MsgPtr->Class;
  3342.                 code  = MsgPtr->Code;
  3343.                 qual  = MsgPtr->Qualifier;
  3344.                 GT_ReplyIMsg(MsgPtr);
  3345.                 switch (class)
  3346.                 {
  3347.                 case IDCMP_RAWKEY:
  3348.                     if (!(qual & IEQUALIFIER_REPEAT))
  3349.                     {   switch (code)
  3350.                         {
  3351.                         case SCAN_F1:
  3352.                             if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  3353.                             {   if (hero[0].control == 0)
  3354.                                 {   hero[0].control = 2;
  3355.                                 } else
  3356.                                 {   hero[0].control--;
  3357.                             }   }
  3358.                             else
  3359.                             {   if (hero[0].control == 2)
  3360.                                 {   hero[0].control = 0;
  3361.                                 } else
  3362.                                 {   hero[0].control++;
  3363.                             }   }
  3364.                             GT_SetGadgetAttrs(CycleGadgetPtr[0], MainWindowPtr, NULL, GTCY_Active, hero[0].control, TAG_DONE);
  3365.                         break;
  3366.                         case SCAN_F2:
  3367.                             if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  3368.                             {   if (hero[1].control == 0)
  3369.                                 {   hero[1].control = 2;
  3370.                                 } else
  3371.                                 {   hero[1].control--;
  3372.                             }   }
  3373.                             else
  3374.                             {   if (hero[1].control == 2)
  3375.                                 {   hero[1].control = 0;
  3376.                                 } else
  3377.                                 {   hero[1].control++;
  3378.                             }   }
  3379.                             GT_SetGadgetAttrs(CycleGadgetPtr[1], MainWindowPtr, NULL, GTCY_Active, hero[1].control, TAG_DONE);
  3380.                         break;
  3381.                         case SCAN_F3:
  3382.                             if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  3383.                             {   if (hero[2].control == 0)
  3384.                                 {   hero[2].control = 2;
  3385.                                 } else
  3386.                                 {   hero[2].control--;
  3387.                             }   }
  3388.                             else
  3389.                             {   if (hero[2].control == 2)
  3390.                                 {   hero[2].control = 0;
  3391.                                 } else
  3392.                                 {   hero[2].control++;
  3393.                             }   }
  3394.                             GT_SetGadgetAttrs(CycleGadgetPtr[2], MainWindowPtr, NULL, GTCY_Active, hero[2].control, TAG_DONE);
  3395.                         break;
  3396.                         case SCAN_F4:
  3397.                             if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  3398.                             {   if (hero[3].control == 0)
  3399.                                 {   hero[3].control = 2;
  3400.                                 } else
  3401.                                 {   hero[3].control--;
  3402.                             }   }
  3403.                             else
  3404.                             {   if (hero[3].control == 2)
  3405.                                 {   hero[3].control = 0;
  3406.                                 } else
  3407.                                 {   hero[3].control++;
  3408.                             }   }
  3409.                             GT_SetGadgetAttrs(CycleGadgetPtr[3], MainWindowPtr, NULL, GTCY_Active, hero[3].control, TAG_DONE);
  3410.                         break;
  3411.                         case SCAN_F5:
  3412.                             if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  3413.                             {   if (hero[4].control == 0)
  3414.                                 {   hero[4].control = 2;
  3415.                                 } else
  3416.                                 {   hero[4].control--;
  3417.                             }   }
  3418.                             else
  3419.                             {   if (hero[4].control == 2)
  3420.                                 {   hero[4].control = 0;
  3421.                                 } else
  3422.                                 {   hero[4].control++;
  3423.                             }   }
  3424.                             GT_SetGadgetAttrs(CycleGadgetPtr[4], MainWindowPtr, NULL, GTCY_Active, hero[4].control, TAG_DONE);
  3425.                         break;
  3426.                         case SCAN_F6:
  3427.                             if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  3428.                             {   if (hero[5].control == 0)
  3429.                                 {   hero[5].control = 2;
  3430.                                 } else
  3431.                                 {   hero[5].control--;
  3432.                             }   }
  3433.                             else
  3434.                             {   if (hero[5].control == 2)
  3435.                                 {   hero[5].control = 0;
  3436.                                 } else
  3437.                                 {   hero[5].control++;
  3438.                             }   }
  3439.                             GT_SetGadgetAttrs(CycleGadgetPtr[5], MainWindowPtr, NULL, GTCY_Active, hero[5].control, TAG_DONE);
  3440.                         break;
  3441.                         case HELP:
  3442.                             helpabout();
  3443.                         break;
  3444.                         default:
  3445.                         break;
  3446.                     }   }
  3447.                 break;
  3448.                 case IDCMP_VANILLAKEY:
  3449.                     code = toupper(code);
  3450.                     switch(code)
  3451.                     {
  3452.                     case ' ':
  3453.                     case 13: // Return or Enter
  3454.                         done = TRUE;
  3455.                     break;
  3456.                     case 27: // Escape
  3457.                         cleanexit(EXIT_SUCCESS);
  3458.                     break;
  3459.                     case '1':
  3460.                     case 'B':
  3461.                         if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  3462.                         {   if (hero[0].control == 0)
  3463.                             {   hero[0].control = 2;
  3464.                             } else
  3465.                             {   hero[0].control--;
  3466.                         }   }
  3467.                         else
  3468.                         {   if (hero[0].control == 2)
  3469.                             {   hero[0].control = 0;
  3470.                             } else
  3471.                             {   hero[0].control++;
  3472.                         }   }
  3473.                         GT_SetGadgetAttrs(CycleGadgetPtr[0], MainWindowPtr, NULL, GTCY_Active, hero[0].control, TAG_DONE);
  3474.                     break;
  3475.                     case '!':
  3476.                         if (hero[0].control == 0)
  3477.                         {   hero[0].control = 2;
  3478.                         } else
  3479.                         {   hero[0].control--;
  3480.                         }
  3481.                         GT_SetGadgetAttrs(CycleGadgetPtr[0], MainWindowPtr, NULL, GTCY_Active, hero[0].control, TAG_DONE);
  3482.                     break;
  3483.                     case '2':
  3484.                     case 'U':
  3485.                         if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  3486.                         {   if (hero[1].control == 0)
  3487.                             {   hero[1].control = 2;
  3488.                             } else
  3489.                             {   hero[1].control--;
  3490.                         }   }
  3491.                         else
  3492.                         {   if (hero[1].control == 2)
  3493.                             {   hero[1].control = 0;
  3494.                             } else
  3495.                             {   hero[1].control++;
  3496.                         }   }
  3497.                         GT_SetGadgetAttrs(CycleGadgetPtr[1], MainWindowPtr, NULL, GTCY_Active, hero[1].control, TAG_DONE);
  3498.                     break;
  3499.                     case '@':
  3500.                         if (hero[1].control == 0)
  3501.                         {   hero[1].control = 2;
  3502.                         } else
  3503.                         {   hero[1].control--;
  3504.                         }
  3505.                         GT_SetGadgetAttrs(CycleGadgetPtr[1], MainWindowPtr, NULL, GTCY_Active, hero[1].control, TAG_DONE);
  3506.                     break;
  3507.                     case '3':
  3508.                     case 'E':
  3509.                         if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  3510.                         {   if (hero[2].control == 0)
  3511.                             {   hero[2].control = 2;
  3512.                             } else
  3513.                             {   hero[2].control--;
  3514.                         }   }
  3515.                         else
  3516.                         {   if (hero[2].control == 2)
  3517.                             {   hero[2].control = 0;
  3518.                             } else
  3519.                             {   hero[2].control++;
  3520.                         }   }
  3521.                         GT_SetGadgetAttrs(CycleGadgetPtr[2], MainWindowPtr, NULL, GTCY_Active, hero[2].control, TAG_DONE);
  3522.                     break;
  3523.                     case '#':
  3524.                         if (hero[2].control == 0)
  3525.                         {   hero[2].control = 2;
  3526.                         } else
  3527.                         {   hero[2].control--;
  3528.                         }
  3529.                         GT_SetGadgetAttrs(CycleGadgetPtr[2], MainWindowPtr, NULL, GTCY_Active, hero[2].control, TAG_DONE);
  3530.                     break;
  3531.                     case '4':
  3532.                     case 'R':
  3533.                         if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  3534.                         {   if (hero[3].control == 0)
  3535.                             {   hero[3].control = 2;
  3536.                             } else
  3537.                             {   hero[3].control--;
  3538.                         }   }
  3539.                         else
  3540.                         {   if (hero[3].control == 2)
  3541.                             {   hero[3].control = 0;
  3542.                             } else
  3543.                             {   hero[3].control++;
  3544.                         }   }
  3545.                         GT_SetGadgetAttrs(CycleGadgetPtr[3], MainWindowPtr, NULL, GTCY_Active, hero[3].control, TAG_DONE);
  3546.                     break;
  3547.                     case '$':
  3548.                         if (hero[3].control == 0)
  3549.                         {   hero[3].control = 2;
  3550.                         } else
  3551.                         {   hero[3].control--;
  3552.                         }
  3553.                         GT_SetGadgetAttrs(CycleGadgetPtr[3], MainWindowPtr, NULL, GTCY_Active, hero[3].control, TAG_DONE);
  3554.                     break;
  3555.                     case '5':
  3556.                     case 'S':
  3557.                         if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  3558.                         {   if (hero[4].control == 0)
  3559.                             {   hero[4].control = 2;
  3560.                             } else
  3561.                             {   hero[4].control--;
  3562.                         }   }
  3563.                         else
  3564.                         {   if (hero[4].control == 2)
  3565.                             {   hero[4].control = 0;
  3566.                             } else
  3567.                             {   hero[4].control++;
  3568.                         }   }
  3569.                         GT_SetGadgetAttrs(CycleGadgetPtr[4], MainWindowPtr, NULL, GTCY_Active, hero[4].control, TAG_DONE);
  3570.                     break;
  3571.                     case '%':
  3572.                         if (hero[4].control == 0)
  3573.                         {   hero[4].control = 2;
  3574.                         } else
  3575.                         {   hero[4].control--;
  3576.                         }
  3577.                         GT_SetGadgetAttrs(CycleGadgetPtr[4], MainWindowPtr, NULL, GTCY_Active, hero[4].control, TAG_DONE);
  3578.                     break;
  3579.                     case '6':
  3580.                     case 'T':
  3581.                         if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  3582.                         {   if (hero[5].control == 0)
  3583.                             {   hero[5].control = 2;
  3584.                             } else
  3585.                             {   hero[5].control--;
  3586.                         }   }
  3587.                         else
  3588.                         {   if (hero[5].control == 2)
  3589.                             {   hero[5].control = 0;
  3590.                             } else
  3591.                             {   hero[5].control++;
  3592.                         }   }
  3593.                         GT_SetGadgetAttrs(CycleGadgetPtr[5], MainWindowPtr, NULL, GTCY_Active, hero[5].control, TAG_DONE);
  3594.                     break;
  3595.                     case '^':
  3596.                         if (hero[5].control == 0)
  3597.                         {   hero[5].control = 2;
  3598.                         } else
  3599.                         {   hero[5].control--;
  3600.                         }
  3601.                         GT_SetGadgetAttrs(CycleGadgetPtr[5], MainWindowPtr, NULL, GTCY_Active, hero[5].control, TAG_DONE);
  3602.                     break;
  3603.                     default:
  3604.                     break;
  3605.                     }
  3606.                 break;
  3607.                 case IDCMP_MENUPICK:
  3608.                     while (code != MENUNULL)
  3609.                     {   ItemPtr = ItemAddress(MenuPtr, code);
  3610.     
  3611.                         switch (MENUNUM(code))
  3612.                         {
  3613.                         case MN_PROJECT:
  3614.                             switch (ITEMNUM(code))
  3615.                             {
  3616.                             case IN_NEW:
  3617.                                 done = TRUE;
  3618.                             break;
  3619.                             case IN_OPEN:
  3620.                                 if (loadgame(TRUE))
  3621.                                 {   done = TRUE;
  3622.                                     loaded = TRUE;
  3623.                                 }
  3624.                             break;
  3625.                             case IN_QUIT:
  3626.                                 cleanexit(EXIT_SUCCESS);
  3627.                             break;
  3628.                             default:
  3629.                                 // IN_SAVE, IN_SAVEAS
  3630.                             break;
  3631.                             }
  3632.                         break;
  3633.                         case MN_HELP:
  3634.                             switch(ITEMNUM(code))
  3635.                             {
  3636.                             case IN_ABOUT:
  3637.                                 helpabout();
  3638.                             break;
  3639.                             default:
  3640.                             break;
  3641.                             }
  3642.                         break;
  3643.                         default:
  3644.                         break;
  3645.                         }
  3646.                         code = ItemPtr->NextSelect;
  3647.                     }
  3648.                 break;
  3649.                 case IDCMP_MOUSEBUTTONS:
  3650.                     if (code == SELECTDOWN && !(qual & IEQUALIFIER_REPEAT))
  3651.                     {   done = TRUE;
  3652.                     }
  3653.                 break;
  3654.                 case IDCMP_REFRESHWINDOW:
  3655.                     GT_BeginRefresh(MainWindowPtr);
  3656.                     GT_EndRefresh(MainWindowPtr, TRUE);
  3657.                 break;
  3658.                 case IDCMP_GADGETUP:
  3659.                     if (addr == SpeedGadgetPtr)
  3660.                     {   speed = code;
  3661.                     } else
  3662.                     {   for (whichhero = 0; whichhero <= HEROES; whichhero++)
  3663.                         {   if (addr == CycleGadgetPtr[whichhero])
  3664.                             {   hero[whichhero].control = code;
  3665.                                 break;
  3666.                     }   }   }
  3667.                 break;
  3668.                 case IDCMP_CLOSEWINDOW:
  3669.                     cleanexit(EXIT_SUCCESS);
  3670.                 break;
  3671.                 default:
  3672.                     ; /* IDCMP_INTUITICKS */
  3673.                 break;
  3674.             }   }
  3675.             if (done)
  3676.             {   done = FALSE;
  3677.                 for (whichhero = 0; whichhero <= HEROES; whichhero++)
  3678.                 {   if (hero[whichhero].control != NONE)
  3679.                     {   done = TRUE;
  3680.                         break;
  3681.                 }   }
  3682.                 if (!done)
  3683.                 {   ; // DisplayBeep(ScreenPtr); // no heroes active
  3684.             }   }
  3685.         } while (!done);
  3686.     }
  3687.  
  3688.     cliload = FALSE;
  3689.     if (!loaded)
  3690.     {   for (whichhero = 0; whichhero <= HEROES; whichhero++)
  3691.         {   GT_SetGadgetAttrs(CycleGadgetPtr[whichhero], MainWindowPtr, NULL, GA_Disabled, TRUE, TAG_DONE);
  3692.         }
  3693.         GT_SetGadgetAttrs(SpeedGadgetPtr, MainWindowPtr, NULL, GA_Disabled, TRUE, TAG_DONE);
  3694.     }
  3695.  
  3696.     if (speed == 4)
  3697.     {   tickwait = -1;
  3698.     } else
  3699.     {   tickwait = speed * 8;
  3700. }   }
  3701.  
  3702. MODULE void gain(SLONG whichhero, SLONG glory, SLONG luck)
  3703. {   SLONG result;
  3704.  
  3705.     if (glory == 0 && luck == 0)
  3706.     {   return;
  3707.     }
  3708.  
  3709.     if (hero[whichhero].control == HUMAN)
  3710.     {   saywho(HERO, whichhero, TRUE, FALSE);
  3711.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GAIN, "gain"));
  3712.         strcat(saystring, " ");
  3713.         stcl_d(numberstring, glory);
  3714.         strcat(saystring, numberstring);
  3715.         strcat(saystring, " (");
  3716.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_GLORY, "G"));
  3717.         strcat(saystring, ")");
  3718.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_UNCHAR_GLORY, "lory"));
  3719.         strcat(saystring, " ");
  3720.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_OR, "or"));
  3721.         strcat(saystring, " ");
  3722.         stcl_d(numberstring, luck);
  3723.         strcat(saystring, numberstring);
  3724.         strcat(saystring, " (");
  3725.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_LUCK, "L"));
  3726.         strcat(saystring, ")");
  3727.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_UNCHAR_LUCK, "uck"));
  3728.         strcat(saystring, "?");
  3729.         say(LOWER);
  3730.         do
  3731.         {   result = getevent(KEYBOARD, NULL);
  3732.         } while (result != onekey[ONEKEY_GLORY] && result != onekey[ONEKEY_LUCK]);
  3733.         if (result == onekey[ONEKEY_GLORY])
  3734.         {   hero[whichhero].glory += glory;
  3735.         } else
  3736.         {   // assert(result == onekey[ONEKEY_LUCK]);
  3737.             hero[whichhero].luck  += luck;
  3738.     }   }
  3739.     else
  3740.     {   hero[whichhero].luck += luck;
  3741. }   }
  3742.  
  3743. MODULE void move(SLONG whichhero)
  3744. {   SLONG country,
  3745.           decision,
  3746.           freemove,
  3747.           i,
  3748.           movearray[66],
  3749.           moves,
  3750.           oldcountry,
  3751.           stop,
  3752.           whichconnection,
  3753.           whichjarl,
  3754.           whichmove = -1,
  3755.           whichrealmove,
  3756.           whichtreasure,
  3757.           whichsord;
  3758.     FLAG  legal;
  3759.  
  3760. // HEROES
  3761.  
  3762.     if (hero[whichhero].alive)
  3763.     {   select_hero(whichhero, TRUE);
  3764.         moves = getmoves(HERO, whichhero, FALSE);
  3765.  
  3766.         if (hero[whichhero].control == HUMAN)
  3767.         {   if
  3768.             (   treasure[FREYFAXI].possessortype == HERO
  3769.              && treasure[FREYFAXI].possessor     == whichhero
  3770.             )
  3771.             {   // assert(treasure[FREYFAXI].where == -1);
  3772.                 // assert(faxirides >= 1);
  3773.  
  3774.                 if (ask_faxi(HERO, whichhero))
  3775.                 {   moves = getmoves(HERO, whichhero, TRUE);
  3776.             }   }
  3777.  
  3778.             movearray[0] = hero[whichhero].where;
  3779.             whichrealmove = 1;
  3780.             if (moves >= 1)
  3781.             {   oldcountry = hero[whichhero].where;
  3782.                 whichmove     =
  3783.                 whichrealmove = 1;
  3784.                 freemove = FALSE;
  3785.                 do
  3786.                 {   saywho(HERO, whichhero, FALSE, FALSE);
  3787.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IN, "in"));
  3788.                     strcat(saystring, " ");
  3789.                     strcat(saystring, world[hero[whichhero].where].name);
  3790.                     strcat(saystring, ", ");
  3791.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_MOVE, "move"));
  3792.                     strcat(saystring, " ");
  3793.                     stcl_d(numberstring, whichmove);
  3794.                     strcat(saystring, numberstring);
  3795.                     strcat(saystring, " ");
  3796.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_OF, "of"));
  3797.                     strcat(saystring, " ");
  3798.                     stcl_d(numberstring, moves);
  3799.                     strcat(saystring, numberstring);
  3800.                     strcat(saystring, "?");
  3801.                     say(LOWER);
  3802.                     do
  3803.                     {   country = getevent(COUNTRY, NULL);
  3804.                     } while ((country < -3 || country > 65) || country == -1);
  3805.                     if (country == -3)
  3806.                     {   break;
  3807.                     } elif (country == -2)
  3808.                     {   whichmove     =
  3809.                         whichrealmove = 1;
  3810.                         unslot_hero(whichhero);
  3811.                         hero[whichhero].where = oldcountry;
  3812.                         move_hero(whichhero, TRUE);
  3813.                         freemove = FALSE;
  3814.                     } else
  3815.                     {   legal = FALSE;
  3816.                         for (whichconnection = 0; whichconnection <= CONNECTIONS; whichconnection++)
  3817.                         {   if (world[hero[whichhero].where].connection[whichconnection] == country)
  3818.                             {   legal = TRUE;
  3819.                                 break; // for speed
  3820.                         }   }
  3821.                         if (legal)
  3822.                         {   if
  3823.                             (   hero[whichhero].sea == BAD
  3824.                              && (   world[country].type == SEA
  3825.                                  || world[country].type == ISLE
  3826.                             )   )
  3827.                             {   legal = FALSE;
  3828.                                 saywho(HERO, whichhero, FALSE, FALSE);
  3829.                                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_M_N_T_B_S_T_T, "may not travel by sea this turn"));
  3830.                                 strcat(saystring, ".");
  3831.                                 say(LOWER);
  3832.                                 anykey();
  3833.                         }   }
  3834.                         if (legal)
  3835.                         {   unslot_hero(whichhero);
  3836.                             hero[whichhero].where = country;
  3837.                             move_hero(whichhero, TRUE);
  3838.                             if (whichrealmove <= 65)
  3839.                             {    movearray[whichrealmove++] = country;
  3840.                             }
  3841.                             if (hero[whichhero].sea == GOOD)
  3842.                             {   if (!freemove)
  3843.                                 {   if
  3844.                                     (   world[hero[whichhero].where].type == SEA
  3845.                                      || world[hero[whichhero].where].type == ISLE
  3846.                                     )
  3847.                                     {   freemove = TRUE;
  3848.                                     }
  3849.                                     whichmove++;
  3850.                                 } else
  3851.                                 {   if
  3852.                                     (   world[hero[whichhero].where].type == LAND
  3853.                                     )
  3854.                                     {   freemove = FALSE;
  3855.                                         whichmove++;
  3856.                             }   }   }
  3857.                             else
  3858.                             {   whichmove++;
  3859.                         }   }
  3860.                         else
  3861.                         {   ; // DisplayBeep(ScreenPtr);
  3862.                     }   }
  3863.                 } while (whichmove <= moves);
  3864.             }
  3865.  
  3866. /* We ask instead of automatically taking because theoretically a hero
  3867. might want to pass on the opportunity, so he can allow one of his jarls
  3868. in the same square to take the treasure. */
  3869.  
  3870.             for (i = 0; i < whichrealmove; i++)
  3871.             {   for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3872.                 {   if (movearray[i] == jarl[whichjarl].where && jarl[whichjarl].hero == whichhero)
  3873.                     {   // hero moved past jarl during move
  3874.                         hero[whichhero].wealth += jarl[whichjarl].wealth;
  3875.                         jarl[whichjarl].wealth = 0;
  3876.             }   }   }
  3877.  
  3878.             for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  3879.             {   if (treasure[whichtreasure].possessortype == KINGDOM && treasure[whichtreasure].where == hero[whichhero].where)
  3880.                 {   // assert(treasure[whichtreasure].possessor = -1);
  3881.  
  3882.                     asktreasure(HERO, whichhero, whichtreasure);
  3883.             }   }
  3884.  
  3885.             if (needsord(HERO, whichhero))
  3886.             {   for (whichsord = 0; whichsord <= SORDS; whichsord++)
  3887.                 {   if (sord[whichsord].possessortype == KINGDOM && sord[whichsord].where == hero[whichhero].where)
  3888.                     {   // assert(sord[whichsord].possessor = -1);
  3889.                         if (asksord(HERO, whichhero, whichsord))
  3890.                         {   break;
  3891.             }   }   }   }
  3892.  
  3893.             if
  3894.             (   treasure[BROSUNGNECKLACE].possessortype == HERO
  3895.              && treasure[BROSUNGNECKLACE].possessor == whichhero
  3896.             )
  3897.             {   brosung(HERO, whichhero);
  3898.         }   }
  3899.         else
  3900.         {   // assert(hero[whichhero].control == AMIGA);
  3901.  
  3902.             movearray[0] = hero[whichhero].where;
  3903.             whichrealmove = 1;
  3904.             if (moves >= 1)
  3905.             {   saywho(HERO, whichhero, FALSE, FALSE);
  3906.                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_MOVING, "is moving"));
  3907.                 strcat(saystring, "...");
  3908.                 say(LOWER);
  3909.                 freemove = FALSE;
  3910.  
  3911.                 if
  3912.                 (   hero[whichhero].wounded
  3913.                  && (   hero[whichhero].rune == ING
  3914.                      || hero[whichhero].where == hero[whichhero].homewhere
  3915.                 )   )
  3916.                 {   stop = TRUE;
  3917.                 } else
  3918.                 {   stop = assess(HERO, hero[whichhero].where);
  3919.                 }
  3920.  
  3921.                 for (whichmove = 1; whichmove <= moves; whichmove++)
  3922.                 {   if (!stop)
  3923.                     {   stop = assess(HERO, whichhero);
  3924.                     }
  3925.                     if (stop)
  3926.                     {   break;
  3927.                     }
  3928.  
  3929.                     do
  3930.                     {   decision = rand() % (CONNECTIONS + 1);
  3931.                     } while (world[hero[whichhero].where].connection[decision] == -1);
  3932.  
  3933.                     if
  3934.                     (   hero[whichhero].sea == BAD
  3935.                      && (   world[world[hero[whichhero].where].connection[decision]].type == SEA
  3936.                          || world[world[hero[whichhero].where].connection[decision]].type == ISLE
  3937.                     )   )
  3938.                     {   whichmove--;
  3939.                     } else
  3940.                     {   unslot_hero(whichhero);
  3941.                         hero[whichhero].where = world[hero[whichhero].where].connection[decision];
  3942.                         move_hero(whichhero, TRUE);
  3943.                         if (whichrealmove <= 65)
  3944.                         {   movearray[whichrealmove++] = hero[whichhero].where;
  3945.                         }
  3946.  
  3947.                         if (hero[whichhero].sea == GOOD)
  3948.                         {   if (!freemove)
  3949.                             {   if
  3950.                                 (   world[hero[whichhero].where].type == SEA
  3951.                                  || world[hero[whichhero].where].type == ISLE
  3952.                                 )
  3953.                                 {   freemove = TRUE;
  3954.                             }   }
  3955.                             else
  3956.                             {   if
  3957.                                 (   world[hero[whichhero].where].type == LAND
  3958.                                 )
  3959.                                 {   freemove = FALSE;
  3960.                                 } else
  3961.                                 {   whichmove--;
  3962.             }   }   }   }   }   }
  3963.  
  3964.             for (i = 0; i < whichrealmove; i++)
  3965.             {   for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  3966.                 {   if (movearray[i] == jarl[whichjarl].where && jarl[whichjarl].hero == whichhero)
  3967.                     {   // hero moved past jarl during move
  3968.                         hero[whichhero].wealth += jarl[whichjarl].wealth;
  3969.                         jarl[whichjarl].wealth = 0;
  3970.             }   }   }
  3971.  
  3972.             // Amiga always takes whatever it can.
  3973.             for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  3974.             {   if (treasure[whichtreasure].possessortype == KINGDOM && treasure[whichtreasure].where == hero[whichhero].where)
  3975.                 {   // assert(treasure[whichtreasure].possessor = -1);
  3976.  
  3977.                     remove_treasure(whichtreasure, TRUE);
  3978.                     treasure[whichtreasure].possessortype = HERO;
  3979.                     treasure[whichtreasure].possessor     = whichhero;
  3980.                     treasure[whichtreasure].where         = -1;
  3981.  
  3982.                     saywho(HERO, whichhero, FALSE, FALSE);
  3983.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES_THE, "takes the"));
  3984.                     strcat(saystring, " ");
  3985.                     strcat(saystring, treasure[whichtreasure].name);
  3986.                     strcat(saystring, ".");
  3987.                     say(LOWER);
  3988.                     anykey();
  3989.             }   }
  3990.  
  3991.             if (needsord(HERO, whichhero))
  3992.             {   for (whichsord = 0; whichsord <= SORDS; whichsord++)
  3993.                 {   if (sord[whichsord].possessortype == KINGDOM && sord[whichsord].where == hero[whichhero].where)
  3994.                     {   // assert(sord[whichsord].possessor = -1);
  3995.  
  3996.                         remove_sord(whichsord, TRUE);
  3997.                         sord[whichsord].possessortype = HERO;
  3998.                         sord[whichsord].possessor     = whichhero;
  3999.                         sord[whichsord].where         = -1;
  4000.  
  4001.                         saywho(HERO, whichhero, FALSE, FALSE);
  4002.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES_SWORD, "takes sword"));
  4003.                         strcat(saystring, " ");
  4004.                         strcat(saystring, sord[whichsord].name);
  4005.                         strcat(saystring, ".");
  4006.                         say(LOWER);
  4007.                         anykey();
  4008.  
  4009.                         break;
  4010.         }   }   }   }
  4011.  
  4012.         // check healing
  4013.  
  4014.         if
  4015.         (   whichmove == 1
  4016.          && hero[whichhero].wounded
  4017.          && (   hero[whichhero].where == hero[whichhero].homewhere
  4018.              || hero[whichhero].rune == ING
  4019.         )   )
  4020.         {   hero[whichhero].wounded = FALSE;
  4021.             saywho(HERO, whichhero, FALSE, FALSE);
  4022.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HEALS, "heals"));
  4023.             strcat(saystring, ".");
  4024.             say(LOWER);
  4025.             anykey();
  4026.         }
  4027.         deselect_hero(whichhero, TRUE);
  4028.  
  4029.         // JARLS
  4030.  
  4031.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  4032.         {   if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
  4033.             {   select_jarl(whichjarl, TRUE);
  4034.                 moves = getmoves(JARL, whichjarl, FALSE);
  4035.                 if (hero[whichhero].control == HUMAN)
  4036.                 {   if
  4037.                     (   treasure[FREYFAXI].possessortype == JARL
  4038.                      && treasure[FREYFAXI].possessor     == whichjarl
  4039.                     )
  4040.                     {   // assert(treasure[FREYFAXI].where == -1);
  4041.                         // assert(faxirides >= 1);
  4042.  
  4043.                         if (ask_faxi(JARL, whichjarl))
  4044.                         {   moves = getmoves(JARL, whichjarl, TRUE);
  4045.                     }   }
  4046.  
  4047.                     movearray[0] = jarl[whichjarl].where;
  4048.                     whichmove = 1;
  4049.                     if (moves >= 1)
  4050.                     {   oldcountry = jarl[whichjarl].where;
  4051.                         do
  4052.                         {   saywho(JARL, whichjarl, FALSE, FALSE);
  4053.                             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IN, "in"));
  4054.                             strcat(saystring, " ");
  4055.                             strcat(saystring, world[jarl[whichjarl].where].name);
  4056.                             strcat(saystring, ", ");
  4057.                             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_MOVE, "move"));
  4058.                             strcat(saystring, " ");
  4059.                             stcl_d(numberstring, whichmove);
  4060.                             strcat(saystring, numberstring);
  4061.                             strcat(saystring, " ");
  4062.                             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_OF, "of"));
  4063.                             strcat(saystring, " ");
  4064.                             stcl_d(numberstring, moves);
  4065.                             strcat(saystring, numberstring);
  4066.                             strcat(saystring, "?");
  4067.                             say(LOWER);
  4068.                             do
  4069.                             {   country = getevent(COUNTRY, NULL);
  4070.                             } while ((country < -3 || country > 65) || country == -1);
  4071.                             if (country == -3)
  4072.                             {   break;
  4073.                             } elif (country == -2)
  4074.                             {   whichmove = 1;
  4075.                                 unslot_jarl(whichjarl);
  4076.                                 jarl[whichjarl].where = oldcountry;
  4077.                                 move_jarl(whichjarl, TRUE);
  4078.                             } else
  4079.                             {   legal = FALSE;
  4080.                                 for (whichconnection = 0; whichconnection <= CONNECTIONS; whichconnection++)
  4081.                                 {   if (world[jarl[whichjarl].where].connection[whichconnection] == country)
  4082.                                     {   legal = TRUE;
  4083.                                         break; // for speed
  4084.                                 }   }
  4085.                                 if (legal)
  4086.                                 {   if
  4087.                                     (   jarl[whichjarl].sea == BAD
  4088.                                      && (   world[country].type == SEA
  4089.                                          || world[country].type == ISLE
  4090.                                     )   )
  4091.                                     {   legal = FALSE;
  4092.                                         saywho(JARL, whichjarl, FALSE, FALSE);
  4093.                                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_M_N_T_B_S_T_T, "may not travel by sea this turn"));
  4094.                                         strcat(saystring, ".");
  4095.                                         say(LOWER);
  4096.                                         anykey();
  4097.                                 }   }
  4098.                                 if (legal)
  4099.                                 {   unslot_jarl(whichjarl);
  4100.                                     jarl[whichjarl].where = country;
  4101.                                     move_jarl(whichjarl, TRUE);
  4102.                                     movearray[whichmove] = country;
  4103.                                     whichmove++;
  4104.                                 } else
  4105.                                 {   ; // DisplayBeep(ScreenPtr);
  4106.                             }   }
  4107.                         } while (whichmove <= moves);
  4108.                     }
  4109.  
  4110.                     for (i = 0; i < whichmove; i++)
  4111.                     {   if (movearray[i] == hero[whichhero].where)
  4112.                         {   // jarl moved past hero during move
  4113.                             hero[whichhero].wealth += jarl[whichjarl].wealth;
  4114.                             jarl[whichjarl].wealth = 0;
  4115.                     }   }
  4116.  
  4117.                     for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  4118.                     {   if (treasure[whichtreasure].possessortype == KINGDOM && treasure[whichtreasure].where == jarl[whichjarl].where)
  4119.                         {   // assert(treasure[whichtreasure].possessor = -1);
  4120.  
  4121.                             asktreasure(JARL, whichjarl, whichtreasure);
  4122.                     }   }
  4123.  
  4124.                     if (needsord(JARL, whichjarl))
  4125.                     {   for (whichsord = 0; whichsord <= SORDS; whichsord++)
  4126.                         {   if (sord[whichsord].possessortype == KINGDOM && sord[whichsord].where == jarl[whichjarl].where)
  4127.                             {   // assert(sord[whichsord].possessor = -1);
  4128.  
  4129.                                 if (asksord(JARL, whichjarl, whichsord))
  4130.                                 {   break;
  4131.                     }   }   }   }
  4132.                     if
  4133.                     (   treasure[BROSUNGNECKLACE].possessortype == JARL
  4134.                      && treasure[BROSUNGNECKLACE].possessor == whichjarl
  4135.                     )
  4136.                     {   brosung(JARL, whichjarl);
  4137.                 }   }
  4138.                 elif (hero[whichhero].control == AMIGA)
  4139.                 {   saywho(JARL, whichjarl, FALSE, FALSE);
  4140.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_MOVING, "is moving"));
  4141.                     strcat(saystring, "...");
  4142.                     say(LOWER);
  4143.  
  4144.                     movearray[0] = jarl[whichjarl].where;
  4145.                     whichmove = 1;
  4146.                     if (moves >= 1)
  4147.                     {   for (whichmove = 1; whichmove <= moves; whichmove++)
  4148.                         {   stop = assess(JARL, whichjarl);
  4149.                             if (stop)
  4150.                             {   break;
  4151.                             }
  4152.  
  4153.                             do
  4154.                             {   decision = rand() % (CONNECTIONS + 1);
  4155.                             } while (world[jarl[whichjarl].where].connection[decision] == -1);
  4156.  
  4157.                             if
  4158.                             (   jarl[whichjarl].sea == BAD
  4159.                              && (   world[world[jarl[whichjarl].where].connection[decision]].type == SEA
  4160.                                  || world[world[jarl[whichjarl].where].connection[decision]].type == ISLE
  4161.                             )   )
  4162.                             {   whichmove--;
  4163.                             } else
  4164.                             {   unslot_jarl(whichjarl);
  4165.                                 jarl[whichjarl].where = world[jarl[whichjarl].where].connection[decision];
  4166.                                 move_jarl(whichjarl, TRUE);
  4167.                                 movearray[whichmove] = jarl[whichjarl].where;
  4168.                     }   }   }
  4169.  
  4170.                     for (i = 0; i < whichmove; i++)
  4171.                     {   if (movearray[i] == hero[whichhero].where)
  4172.                         {   // jarl moved past hero during move
  4173.                             hero[whichhero].wealth += jarl[whichjarl].wealth;
  4174.                             jarl[whichjarl].wealth = 0;
  4175.                     }   }
  4176.  
  4177.                     // Amiga always takes whatever it can.
  4178.                     for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  4179.                     {   if (treasure[whichtreasure].possessortype == KINGDOM && treasure[whichtreasure].where == jarl[whichjarl].where)
  4180.                         {   // assert(treasure[whichtreasure].possessor = -1);
  4181.  
  4182.                             remove_treasure(whichtreasure, TRUE);
  4183.                             treasure[whichtreasure].possessortype = JARL;
  4184.                             treasure[whichtreasure].possessor     = whichjarl;
  4185.                             treasure[whichtreasure].where         = -1;
  4186.  
  4187.                             saywho(JARL, whichjarl, FALSE, FALSE);
  4188.                             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES_THE, "takes the"));
  4189.                             strcat(saystring, " ");
  4190.                             strcat(saystring, treasure[whichtreasure].name);
  4191.                             strcat(saystring, ".");
  4192.                             say(LOWER);
  4193.                             anykey();
  4194.                     }   }
  4195.  
  4196.                     if (needsord(JARL, whichjarl))
  4197.                     {   for (whichsord = 0; whichsord <= SORDS; whichsord++)
  4198.                         {   if (sord[whichsord].possessortype == KINGDOM && sord[whichsord].where == jarl[whichjarl].where)
  4199.                             {   // assert(sord[whichsord].possessor = -1);
  4200.             
  4201.                                 remove_sord(whichsord, TRUE);
  4202.                                 sord[whichsord].possessortype = HERO;
  4203.                                 sord[whichsord].possessor     = whichhero;
  4204.                                 sord[whichsord].where         = -1;
  4205.  
  4206.                                 saywho(JARL, whichjarl, FALSE, FALSE);
  4207.                                 strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES_SWORD, "takes sword"));
  4208.                                 strcat(saystring, " ");
  4209.                                 strcat(saystring, sord[whichsord].name);
  4210.                                 strcat(saystring, ".");
  4211.                                 say(LOWER);
  4212.                                 anykey();
  4213.  
  4214.                                 break;
  4215.                 }   }   }   }
  4216.                 deselect_jarl(whichjarl, TRUE);
  4217. }   }   }   }
  4218.  
  4219. MODULE void helpabout(void)
  4220. {   SBYTE                line;
  4221.     FLAG                 done          = FALSE;
  4222.     ULONG                class;
  4223.     UWORD                code, qual;
  4224.     struct IntuiMessage* MsgPtr;
  4225.  
  4226.     if (!(HelpWindowPtr = (struct Window *) OpenWindowTags(NULL,
  4227.         WA_Left,          (SCREENXPIXEL / 2) - (ABOUTXPIXEL / 2),
  4228.         WA_Top,           (SCREENYPIXEL / 2) - (ABOUTYPIXEL / 2),
  4229.         WA_Width,         ABOUTXPIXEL,
  4230.         WA_Height,        ABOUTYPIXEL,
  4231.         WA_IDCMP,         IDCMP_CLOSEWINDOW | IDCMP_RAWKEY,
  4232.         WA_Title,         abouttitle,
  4233.         WA_Gadgets,       NULL,
  4234.         WA_CustomScreen,  ScreenPtr,
  4235.         WA_DragBar,       TRUE,
  4236.         WA_CloseGadget,   TRUE,
  4237.         WA_NoCareRefresh, TRUE,
  4238.         WA_Activate,      TRUE,
  4239.     TAG_DONE))
  4240.     )
  4241.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open About... window!\0", 24);
  4242.         cleanexit(EXIT_FAILURE);
  4243.     } else
  4244.     {   SetAPen(HelpWindowPtr->RPort, LIGHTGREY);
  4245.         RectFill(HelpWindowPtr->RPort, 8, 13, ABOUTXPIXEL - 10, ABOUTYPIXEL - 6);
  4246.         SetAPen(HelpWindowPtr->RPort, BLACK);
  4247.         SetDrMd(HelpWindowPtr->RPort, JAM1);
  4248.         for (line = 0; line <= ABOUTLINES; line++)
  4249.         {   Move(HelpWindowPtr->RPort, about[line].x, about[line].y);
  4250.             Text(HelpWindowPtr->RPort, about[line].text, (SBYTE) strlen(about[line].text));
  4251.         }
  4252.  
  4253.         DrawBevelBox(HelpWindowPtr->RPort, 16, 20, 44 + 4, 38 + 4, GT_VisualInfo, VisualInfoPtr, GTBB_Recessed, TRUE, TAG_END);
  4254.  
  4255.         drawabout();
  4256.  
  4257.         while(!done)
  4258.         {   Wait(1L << HelpWindowPtr->UserPort->mp_SigBit);
  4259.             while (MsgPtr = (struct IntuiMessage *) GetMsg(HelpWindowPtr->UserPort))
  4260.             {   class  = MsgPtr->Class;
  4261.                 code   = MsgPtr->Code;
  4262.                 qual   = MsgPtr->Qualifier;
  4263.                 ReplyMsg((struct Message *) MsgPtr);
  4264.                 switch(class)
  4265.                 {
  4266.                 case IDCMP_CLOSEWINDOW:
  4267.                     done = TRUE;
  4268.                 break;
  4269.                 case IDCMP_RAWKEY:
  4270.                     if (!(qual & IEQUALIFIER_REPEAT) && code < KEYUP && (code < FIRSTQUALIFIER || code > LASTQUALIFIER))
  4271.                     {   done = TRUE;
  4272.                     }
  4273.                 break;
  4274.                 default:
  4275.                 break;
  4276.         }   }   }
  4277.         CloseWindow(HelpWindowPtr);
  4278.         HelpWindowPtr = NULL;
  4279.         clearkybd();
  4280. }   }
  4281.  
  4282. MODULE void resettime(void)
  4283. {   struct timerequest* TimerIORequestPtr;
  4284.     struct timeval      timeval;
  4285.  
  4286.     if (!(TimerIORequestPtr = (struct timerequest *) AllocVec(sizeof(struct timerequest), MEMF_PUBLIC | MEMF_CLEAR)))
  4287.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Out of memory!\0", 24);
  4288.         cleanexit(EXIT_FAILURE);
  4289.     }
  4290.     if (OpenDevice(TIMERNAME, UNIT_MICROHZ, (struct IORequest *) TimerIORequestPtr, 0))
  4291.     {   FreeVec(TimerIORequestPtr);
  4292.         DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open timer.device!\0", 24);
  4293.         cleanexit(EXIT_FAILURE);
  4294.     }
  4295.     TimerBase = (struct Library *) TimerIORequestPtr->tr_node.io_Device;
  4296.     GetSysTime(&timeval);
  4297.     srand((UWORD) timeval.tv_micro);
  4298.     // no need to abort timer I/O requests, as we never send any
  4299.     CloseDevice((struct IORequest *) TimerIORequestPtr);
  4300.     FreeVec(TimerIORequestPtr);
  4301. }
  4302.  
  4303. MODULE void anykey(void)
  4304. {   if (tickwait != 0)
  4305.     {   getevent(ANYKEY, NULL);
  4306. }   }
  4307. MODULE void waitkey(void)
  4308. {   SLONG realtickwait = tickwait;
  4309.  
  4310.     tickwait = -1;
  4311.     getevent(ANYKEY, NULL);
  4312.     tickwait = realtickwait;
  4313. }
  4314.  
  4315. MODULE SLONG getluck(SLONG whichhero)
  4316. {   SLONG result;
  4317.  
  4318.     while(1)
  4319.     {   do
  4320.         {   result = getevent(KEYBOARD, NULL);
  4321.         } while (result < '0' || result > '9');
  4322.  
  4323.         if (result == '0')
  4324.         {   return(0);
  4325.         } else
  4326.         {   result -= '0';
  4327.         }
  4328.  
  4329.         if (result > hero[whichhero].luck)
  4330.         {   ; // DisplayBeep(ScreenPtr);
  4331.         } else
  4332.         {   hero[whichhero].luck -= result;
  4333.             return(result);
  4334. }   }   }
  4335.  
  4336. MODULE void phase3(void)
  4337. {   FLAG  ok;
  4338.     SBYTE whichhero, whichcountry, whichjarl;
  4339.  
  4340.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  4341.     {   if (hero[whichhero].control != NONE && !(hero[whichhero].verydead))
  4342.         /* Note that we even do this for dead heroes: they can keep their
  4343.            kingdoms (for now) where they have jarls, as they may be
  4344.            promoting a jarl, in which case they are allowed to keep their
  4345.            kingdoms. */
  4346.         {   for (whichcountry = 0; whichcountry <= 35; whichcountry++)
  4347.             {   if (world[whichcountry].hero == whichhero)
  4348.                 {   // determine whether the hero or one of his jarls is there
  4349.  
  4350.                     ok = FALSE;
  4351.                     if (!world[whichcountry].is)
  4352.                     {   if (hero[whichhero].where == whichcountry)
  4353.                         {   ok = TRUE;
  4354.                             hero[whichhero].wealth += world[whichcountry].tax;
  4355.                             if (hero[whichhero].rune == GEOFU)
  4356.                             {   hero[whichhero].wealth++;
  4357.                         }   }
  4358.                         else
  4359.                         {   for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  4360.                             {   if
  4361.                                 (   jarl[whichjarl].alive
  4362.                                  && jarl[whichjarl].hero == whichhero
  4363.                                  && jarl[whichjarl].where == whichcountry
  4364.                                 ) // taxes are given to the first friendly jarl found
  4365.                                 {   ok = TRUE;
  4366.                                     jarl[whichjarl].wealth += world[whichcountry].tax;
  4367.                                     if (hero[whichhero].rune == GEOFU)
  4368.                                     {   jarl[whichjarl].wealth++;
  4369.                                     }
  4370.                                     break;
  4371.                     }   }   }   }
  4372.  
  4373.                     if (!ok)
  4374.                     {   world[whichcountry].hero = -1;
  4375.                         darken();
  4376.  
  4377.                         strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO, "Hero"));
  4378.                         strcat(saystring, " ");
  4379.                         strcat(saystring, hero[whichhero].name);
  4380.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_KINGDOM, "'s kingdom"));
  4381.                         strcat(saystring, " ");
  4382.                         strcat(saystring, world[whichcountry].name);
  4383.                         strcat(saystring, " (");
  4384.                         stcl_d(numberstring, world[whichcountry].tax);
  4385.                         strcat(saystring, numberstring);
  4386.                         strcat(saystring, ") ");
  4387.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HAS_BEEN_OVERRUN, "has been overrun"));
  4388.                         strcat(saystring, ".");
  4389.                         say(LOWER);
  4390.                         anykey();
  4391. }   }   }   }   }   }
  4392.  
  4393. MODULE void gods(SLONG whichhero)
  4394. {   SLONG whichgod, whichprayer, decision;
  4395.     FLAG  heard;
  4396.  
  4397.     whichgod    = rand() % 6;
  4398.     whichprayer = d6();
  4399.  
  4400.     switch(whichgod)
  4401.     {
  4402.     case FREY:
  4403.         strcpy(saystring, "Frey ");
  4404.         heard = FALSE;
  4405.         if (whichprayer <= 4)
  4406.         {   // assert(whichprayer >= 1);
  4407.             hero[whichhero].maidens++;
  4408.  
  4409.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_W_S_A_M_T_H_H, "will send a maiden to heal hero"));
  4410.             strcat(saystring, " ");                                    
  4411.             strcat(saystring, hero[whichhero].name);
  4412.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_NEXT_WOUND, "'s next wound"));
  4413.             strcat(saystring, ".");
  4414.         } else
  4415.         {   // assert(whichprayer == 5 || whichprayer == 6);
  4416.             hero[whichhero].maidens += 2;
  4417.  
  4418.             strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_W_S_A_M_T_H_H, "will send a maiden to heal hero"));
  4419.             strcat(saystring, " ");
  4420.             strcat(saystring, hero[whichhero].name);
  4421.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_NEXT_TWO_WOUNDS, "'s next two wounds"));
  4422.             strcat(saystring, ".");
  4423.         }
  4424.     break;
  4425.     case LOKI:
  4426.         strcpy(saystring, "Loki ");
  4427.         heard = FALSE;
  4428.         if (whichprayer <= 3)
  4429.         {   // assert(whichprayer >= 0);
  4430.  
  4431.             hero[whichhero].luck--;
  4432.             if (hero[whichhero].luck < 0)
  4433.             {   hero[whichhero].luck = 0;
  4434.             }
  4435.  
  4436.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_A_P_O_L_F_H, "steals a point of luck from hero"));
  4437.             strcat(saystring, " ");
  4438.             strcat(saystring, hero[whichhero].name);
  4439.             strcat(saystring, ".");
  4440.         } else
  4441.         {   // assert(whichprayer >= 4 && whichprayer <= 6);
  4442.  
  4443.             hero[whichhero].luck++;
  4444.  
  4445.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GRANTS_HERO, "grants hero"));
  4446.             strcat(saystring, " ");
  4447.             strcat(saystring, hero[whichhero].name);
  4448.             strcat(saystring, " ");                                                        
  4449.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_A_P_O_L_F_H_D, "a point of luck for his daring"));
  4450.             strcat(saystring, ".");
  4451.         }
  4452.     break;
  4453.     case NJORD:
  4454.         strcpy(saystring, "Njord ");
  4455.         heard = FALSE;
  4456.         if (whichprayer == 1 || whichprayer == 2)
  4457.         {   hero[whichhero].sea = GOOD;
  4458.  
  4459.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO, "aids hero"));
  4460.             strcat(saystring, " ");
  4461.             strcat(saystring, hero[whichhero].name);
  4462.             strcat(saystring, " ");
  4463.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TO_MOVE_BY_SEA_NEXT_TURN, "to move by sea next turn"));
  4464.             strcat(saystring, ".");
  4465.         } elif (whichprayer == 3 || whichprayer == 4)
  4466.         {   decision = d6();
  4467.             hero[whichhero].wealth += decision;
  4468.  
  4469.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GIVES, "gives"));
  4470.             strcat(saystring, " ");
  4471.             stcl_d(numberstring, decision);
  4472.             strcat(saystring, numberstring);
  4473.             strcat(saystring, " ");
  4474.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS_TO_HERO, "golden marks to hero"));
  4475.             strcat(saystring, " ");
  4476.             strcat(saystring, hero[whichhero].name);
  4477.             strcat(saystring, " ");
  4478.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AS_A_GIFT, "as a gift"));
  4479.             strcat(saystring, ".");
  4480.         } elif (whichprayer == 5)
  4481.         {   decision = d6();
  4482.             if (decision > hero[whichhero].wealth)
  4483.             {   decision = hero[whichhero].wealth;
  4484.             }
  4485.             hero[whichhero].wealth -= decision;
  4486.  
  4487.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES, "takes"));
  4488.             strcat(saystring, " ");
  4489.             stcl_d(numberstring, decision);
  4490.             strcat(saystring, numberstring);
  4491.             strcat(saystring, " ");
  4492.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_GOLDEN_MARKS_FROM_HERO, "golden marks from hero"));
  4493.             strcat(saystring, " ");
  4494.             strcat(saystring, hero[whichhero].name);
  4495.             strcat(saystring, " ");
  4496.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AS_DUE_TRIBUTE, "as due tribute"));
  4497.             strcat(saystring, ".");
  4498.         } else
  4499.         {   // assert(whichprayer == 6);
  4500.             hero[whichhero].sea = BAD;
  4501.  
  4502.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_PREVENTS_HERO, "prevents hero"));
  4503.             strcat(saystring, " ");
  4504.             strcat(saystring, hero[whichhero].name);
  4505.             strcat(saystring, " ");
  4506.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_F_T_B_S_N_T, "from travelling by sea next turn"));
  4507.             strcat(saystring, ".");
  4508.         }
  4509.     break;
  4510.     case ODIN:
  4511.         hero[whichhero].god = ODIN;
  4512.         heard = TRUE;
  4513.         strcpy(saystring, "Odin ");
  4514.     break;
  4515.     case THOR:
  4516.         hero[whichhero].god = THOR;
  4517.         heard = TRUE;
  4518.         strcpy(saystring, "Thor ");
  4519.     break;
  4520.     case TYR:
  4521.         hero[whichhero].god = TYR;
  4522.         heard = TRUE;
  4523.         strcpy(saystring, "Tyr ");
  4524.     break;
  4525.     default:
  4526.     break;
  4527.     }
  4528.     if (heard)
  4529.     {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HEARD_THE_PRAYER_OF_HERO, "heard the prayer of hero"));
  4530.         strcat(saystring, " ");
  4531.         strcat(saystring, hero[whichhero].name);
  4532.         strcat(saystring, ".");
  4533.     }
  4534.     say(LOWER);
  4535.     anykey();
  4536. }
  4537.  
  4538. MODULE FLAG loadgame(FLAG aslwindow)
  4539. {   SLONG offset = 12, whichhero, whichjarl, whichmonster, whichcountry,
  4540.           whichslot, whichtreasure, whichsord;
  4541.     TEXT  newpathname[255];
  4542.     BPTR  FileHandle /* = NULL */ ;
  4543.     FLAG  ok;
  4544.  
  4545.     if (aslwindow)
  4546.     {   if
  4547.         (   AslRequestTags
  4548.             (    ASLRqPtr,
  4549.                  ASL_Hail, GetCatalogStr(li.li_Catalog, MSG_LOAD_GAME, "Load Game"),
  4550.                  ASL_FuncFlags, FILF_PATGAD,
  4551.                  TAG_DONE
  4552.             )
  4553.          && *(ASLRqPtr->rf_File)
  4554.         )
  4555.         {   strcpy(newpathname, ASLRqPtr->rf_Dir);
  4556.             AddPart(newpathname, ASLRqPtr->rf_File, 254);
  4557.             ok = TRUE;
  4558.         } else
  4559.         {   ok = FALSE;
  4560.     }   }
  4561.     else
  4562.     {   ok = TRUE;
  4563.         strcpy(newpathname, pathname);
  4564.     }
  4565.  
  4566.     // 'SAGA 1.0' fieldsets are 544 bytes long, plus the version string.
  4567.  
  4568.     if (ok)
  4569.     {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_LOADING, "Loading"));
  4570.         strcat(saystring, " ");
  4571.         strcat(saystring, newpathname);
  4572.         strcat(saystring, "...");
  4573.         say(LOWER);
  4574.  
  4575.         if (!(FileHandle = Open(newpathname, MODE_OLDFILE)))
  4576.         {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_CANT_OPEN, "Can't open"));
  4577.             strcat(saystring, " ");
  4578.             strcat(saystring, newpathname);
  4579.             strcat(saystring, " ");
  4580.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FOR_READING, "for reading"));
  4581.             strcat(saystring, "!");
  4582.             say(LOWER);
  4583.             return(FALSE);
  4584.         }
  4585.  
  4586.         // read file
  4587.         if (Read(FileHandle, IOBuffer, 544) != 544)
  4588.         {   Close(FileHandle);
  4589.             // FileHandle = NULL;
  4590.             strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_CANT_READ_FROM, "Can't read from"));
  4591.             strcat(saystring, " ");
  4592.             strcat(saystring, newpathname);
  4593.             strcat(saystring, "!");
  4594.             say(LOWER);
  4595.             return(FALSE);
  4596.         }
  4597.  
  4598.         if (strcmp(IOBuffer, "SAGA 1.0 "))
  4599.         {   Close(FileHandle);
  4600.             // FileHandle = NULL;
  4601.             strcpy(saystring, newpathname);
  4602.             strcat(saystring, " ");
  4603.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_I_N_A_V_S_G_F, "is not a valid saved game file"));
  4604.             strcat(saystring, "!");
  4605.             say(LOWER);
  4606.             return(FALSE);
  4607.         }
  4608.         turn      = (SLONG) ((SBYTE) IOBuffer[10]);
  4609.         faxirides = (SLONG) ((SBYTE) IOBuffer[11]);
  4610.  
  4611.         for (whichhero = 0; whichhero <= HEROES; whichhero++)
  4612.         {   hero[whichhero].control   = (SLONG) ((SBYTE) IOBuffer[offset++] );
  4613.             hero[whichhero].alive     = (FLAG)  ((SBYTE) IOBuffer[offset++] );
  4614.             hero[whichhero].verydead  = (FLAG)  ((SBYTE) IOBuffer[offset++] );
  4615.             hero[whichhero].moves     = (SLONG) ((SBYTE) IOBuffer[offset++] );
  4616.             hero[whichhero].god       = (SLONG) ((SBYTE) IOBuffer[offset++] );
  4617.             hero[whichhero].rune      = (SLONG) ((SBYTE) IOBuffer[offset++] );
  4618.             hero[whichhero].where     = (SLONG) ((SBYTE) IOBuffer[offset++] );
  4619.             hero[whichhero].homewhere = (SLONG) ((SBYTE) IOBuffer[offset++] );
  4620.             hero[whichhero].promoted  = (SLONG) ((SBYTE) IOBuffer[offset++] );
  4621.             hero[whichhero].wounded   = (FLAG)  ((SBYTE) IOBuffer[offset++] );
  4622.             hero[whichhero].wealth    = (SLONG) ((IOBuffer[offset++] * 256) + IOBuffer[offset++]);
  4623.             hero[whichhero].glory     = (SLONG) ((IOBuffer[offset++] * 256) + IOBuffer[offset++]);
  4624.             hero[whichhero].luck      = (SLONG) ((IOBuffer[offset++] * 256) + IOBuffer[offset++]);
  4625.             hero[whichhero].sea       = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4626.             hero[whichhero].loseturn  = (FLAG)  ((SBYTE) IOBuffer[offset++]);
  4627.             hero[whichhero].maidens   = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4628.         }
  4629.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  4630.         {   jarl[whichjarl].where     = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4631.             jarl[whichjarl].homewhere = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4632.             jarl[whichjarl].face      = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4633.             jarl[whichjarl].hero      = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4634.             jarl[whichjarl].taken     = (FLAG)  ((SBYTE) IOBuffer[offset++]);
  4635.             jarl[whichjarl].sea       = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4636.             jarl[whichjarl].loseturn  = (FLAG)  ((SBYTE) IOBuffer[offset++]);
  4637.             jarl[whichjarl].alive     = (FLAG)  ((SBYTE) IOBuffer[offset++]);
  4638.         }
  4639.         for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  4640.         {   monster[whichmonster].taken    = (FLAG)  ((SBYTE) IOBuffer[offset++]);
  4641.             monster[whichmonster].alive    = (FLAG)  ((SBYTE) IOBuffer[offset++]);
  4642.             monster[whichmonster].where    = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4643.             monster[whichmonster].wealth   = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4644.             monster[whichmonster].sea      = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4645.             offset++; // skip monster[].loseturn
  4646.         }
  4647.         for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  4648.         {   treasure[whichtreasure].taken         = (FLAG)  ((SBYTE) IOBuffer[offset++]);
  4649.             treasure[whichtreasure].possessor     = (FLAG)  ((SBYTE) IOBuffer[offset++]);
  4650.             treasure[whichtreasure].possessortype = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4651.             treasure[whichtreasure].where         = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4652.         }
  4653.         for (whichsord = 0; whichsord <= SORDS; whichsord++)
  4654.         {   sord[whichsord].taken         = (FLAG)  ((SBYTE) IOBuffer[offset++]);
  4655.             sord[whichsord].possessor     = (FLAG)  ((SBYTE) IOBuffer[offset++]);
  4656.             sord[whichsord].possessortype = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4657.             sord[whichsord].where         = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4658.         }
  4659.         for (whichcountry = 0; whichcountry <= 35; whichcountry++)
  4660.         {   world[whichcountry].hero = (SLONG) ((SBYTE) IOBuffer[offset++]);
  4661.             world[whichcountry].is   = (FLAG)  ((SBYTE) IOBuffer[offset++]);
  4662.         }
  4663.         // no need to read version string
  4664.         Close(FileHandle);
  4665.         // FileHandle = NULL;
  4666.  
  4667.         strcpy(pathname, newpathname);
  4668.  
  4669.         for (whichhero = 0; whichhero <= HEROES; whichhero++)
  4670.         {   GT_SetGadgetAttrs(CycleGadgetPtr[whichhero], MainWindowPtr, NULL, GA_Disabled, TRUE, TAG_DONE);
  4671.         }
  4672.         GT_SetGadgetAttrs(SpeedGadgetPtr, MainWindowPtr, NULL, GA_Disabled, TRUE, TAG_DONE);
  4673.  
  4674.         for (whichcountry = 0; whichcountry <= 65; whichcountry++)
  4675.         {   for (whichslot = 0; whichslot <= SLOTS; whichslot++)
  4676.             {   world[whichcountry].slot[whichslot] = FALSE;
  4677.         }   }
  4678.  
  4679.         for (whichhero = 0; whichhero <= HEROES; whichhero++)
  4680.         {   if (hero[whichhero].promoted == -1)
  4681.             {   hero[whichhero].name     = trueheroname[whichhero];
  4682.                 hero[whichhero].strength = HERO_STRENGTH;
  4683.                 hero[whichhero].moves    = HERO_MOVES;
  4684.             } else
  4685.             {   hero[whichhero].name     = jarl[hero[whichhero].promoted].name;
  4686.                 hero[whichhero].strength = jarl[hero[whichhero].promoted].strength;
  4687.                 hero[whichhero].moves    = jarl[hero[whichhero].promoted].moves;
  4688.             }
  4689.             deselect_hero(whichhero, FALSE);
  4690.             if (hero[whichhero].alive)
  4691.             {   move_hero(whichhero, FALSE);
  4692.             } else
  4693.             {   remove_hero(whichhero, FALSE);
  4694.         }   }
  4695.  
  4696.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  4697.         {   jarl[whichjarl].recruitable = FALSE;
  4698.             if (jarl[whichjarl].alive)
  4699.             {   if (jarl[whichjarl].face == FACEUP)
  4700.                 {   revealjarl(whichjarl, FALSE);
  4701.                 } else
  4702.                 {   // assert(jarl[whichjarl].face == FACEDOWN);
  4703.                     hidejarl(whichjarl, FALSE);
  4704.                 }
  4705.                 move_jarl(whichjarl, FALSE);
  4706.             } else
  4707.             {   remove_jarl(whichjarl, FALSE);
  4708.         }   }
  4709.  
  4710.         for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  4711.         {   if (monster[whichmonster].alive)
  4712.             {   move_monster(whichmonster, FALSE);
  4713.             } else
  4714.             {   remove_monster(whichmonster, FALSE);
  4715.         }   }
  4716.  
  4717.         for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  4718.         {   if (treasure[whichtreasure].possessor == -1)
  4719.             {   move_treasure(whichtreasure, FALSE);
  4720.         }   }
  4721.  
  4722.         for (whichsord = 0; whichsord <= SORDS; whichsord++)
  4723.         {   if (sord[whichsord].possessor == -1)
  4724.             {   move_sord(whichsord, FALSE);
  4725.         }   }
  4726.  
  4727.         darken();
  4728.         drawmap();
  4729.         refreshcounters();
  4730.  
  4731.         if (faxirides == -1)
  4732.         {   faxirides = 0;
  4733.             faxi_disappear();
  4734.         }
  4735.  
  4736.         strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_LOADED, "Loaded"));
  4737.         strcat(saystring, " ");
  4738.         strcat(saystring, pathname);
  4739.         strcat(saystring, ".");
  4740.         say(LOWER);
  4741.         return(TRUE);
  4742. }   }
  4743.  
  4744. MODULE void savegame(FLAG saveas)
  4745. {   SLONG offset = 12, whichhero, whichjarl, whichmonster, whichcountry,
  4746.           whichtreasure, whichsord;
  4747.     FLAG  cont = TRUE;
  4748.     TEXT  newpathname[255];
  4749.     BPTR  FileHandle /* = NULL */ ;
  4750.  
  4751.     strcpy(newpathname, pathname);
  4752.     if (saveas || newpathname[0] == 0)
  4753.     {   if
  4754.         (   AslRequestTags
  4755.             (   ASLRqPtr,
  4756.                 ASL_Hail, GetCatalogStr(li.li_Catalog, MSG_SAVE_GAME, "Save Game"),
  4757.                 ASL_FuncFlags, FILF_PATGAD | FILF_SAVE,
  4758.                 TAG_DONE
  4759.             )
  4760.          && *(ASLRqPtr->rf_File) != 0
  4761.         )
  4762.         {   strcpy(newpathname, ASLRqPtr->rf_Dir);
  4763.             AddPart(newpathname, ASLRqPtr->rf_File, 254);
  4764.         } else
  4765.         {   cont = FALSE;
  4766.     }   }
  4767.     if (!cont)
  4768.     {   return;
  4769.     }
  4770.  
  4771.     strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_SAVING, "Saving"));
  4772.     strcat(saystring, " ");
  4773.     strcat(saystring, newpathname);
  4774.     strcat(saystring, "...");
  4775.     say(LOWER);
  4776.  
  4777.     if (!(FileHandle = Open(newpathname, MODE_NEWFILE)))
  4778.     {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_CANT_OPEN, "Can't open"));
  4779.         strcat(saystring, " ");
  4780.         strcat(saystring, newpathname);
  4781.         strcat(saystring, " ");
  4782.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FOR_WRITING, "for writing"));
  4783.         strcat(saystring, "!");
  4784.         say(LOWER);
  4785.         anykey();
  4786.         return;
  4787.     }
  4788.  
  4789.     /* write header
  4790.        SAGA 1.0 *#%
  4791.        012345678901
  4792.        where * is NULL byte and # is turn and % is faxi rides */
  4793.  
  4794.     strcpy(IOBuffer, "SAGA 1.0 ");
  4795.     IOBuffer[10] = (SBYTE) turn;
  4796.     IOBuffer[11] = (SBYTE) faxirides;
  4797.  
  4798.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  4799.     {    IOBuffer[offset++] = (SBYTE) hero[whichhero].control;
  4800.          IOBuffer[offset++] = (SBYTE) hero[whichhero].alive;
  4801.          IOBuffer[offset++] = (SBYTE) hero[whichhero].verydead;
  4802.          IOBuffer[offset++] = (SBYTE) hero[whichhero].moves;
  4803.          IOBuffer[offset++] = (SBYTE) hero[whichhero].god;
  4804.          IOBuffer[offset++] = (SBYTE) hero[whichhero].rune;
  4805.          IOBuffer[offset++] = (SBYTE) hero[whichhero].where;
  4806.          IOBuffer[offset++] = (SBYTE) hero[whichhero].homewhere;
  4807.          IOBuffer[offset++] = (SBYTE) hero[whichhero].promoted;
  4808.          IOBuffer[offset++] = (SBYTE) hero[whichhero].wounded;
  4809.          IOBuffer[offset++] = (UBYTE) (hero[whichhero].wealth / 256);
  4810.          IOBuffer[offset++] = (UBYTE) (hero[whichhero].wealth % 256);
  4811.          IOBuffer[offset++] = (UBYTE) (hero[whichhero].glory  / 256);
  4812.          IOBuffer[offset++] = (UBYTE) (hero[whichhero].glory  % 256);
  4813.          IOBuffer[offset++] = (UBYTE) (hero[whichhero].luck   / 256);
  4814.          IOBuffer[offset++] = (UBYTE) (hero[whichhero].luck   % 256);
  4815.          IOBuffer[offset++] = (SBYTE) hero[whichhero].sea;
  4816.          IOBuffer[offset++] = (SBYTE) hero[whichhero].loseturn;
  4817.          IOBuffer[offset++] = (SBYTE) hero[whichhero].maidens;
  4818.     }
  4819.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  4820.     {    IOBuffer[offset++] = (SBYTE) jarl[whichjarl].where;
  4821.          IOBuffer[offset++] = (SBYTE) jarl[whichjarl].homewhere;
  4822.          IOBuffer[offset++] = (SBYTE) jarl[whichjarl].face;
  4823.          IOBuffer[offset++] = (SBYTE) jarl[whichjarl].hero;
  4824.          IOBuffer[offset++] = (SBYTE) jarl[whichjarl].taken;
  4825.          IOBuffer[offset++] = (SBYTE) jarl[whichjarl].sea;
  4826.          IOBuffer[offset++] = (SBYTE) jarl[whichjarl].loseturn;
  4827.          IOBuffer[offset++] = (SBYTE) jarl[whichjarl].alive;
  4828.     }
  4829.     for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  4830.     {    IOBuffer[offset++] = (SBYTE) monster[whichmonster].taken;
  4831.          IOBuffer[offset++] = (SBYTE) monster[whichmonster].alive;
  4832.          IOBuffer[offset++] = (SBYTE) monster[whichmonster].where;
  4833.          IOBuffer[offset++] = (SBYTE) monster[whichmonster].wealth;
  4834.          IOBuffer[offset++] = (SBYTE) monster[whichmonster].sea;
  4835.          IOBuffer[offset++] = (SBYTE) 0; // skip monster loseturn
  4836.     }
  4837.     for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  4838.     {    IOBuffer[offset++] = (SBYTE) treasure[whichtreasure].taken;
  4839.          IOBuffer[offset++] = (SBYTE) treasure[whichtreasure].possessor;
  4840.          IOBuffer[offset++] = (SBYTE) treasure[whichtreasure].possessortype;
  4841.          IOBuffer[offset++] = (SBYTE) treasure[whichtreasure].where;
  4842.     }
  4843.     for (whichsord = 0; whichsord <= SORDS; whichsord++)
  4844.     {    IOBuffer[offset++] = (SBYTE) sord[whichsord].taken;
  4845.          IOBuffer[offset++] = (SBYTE) sord[whichsord].possessor;
  4846.          IOBuffer[offset++] = (SBYTE) sord[whichsord].possessortype;
  4847.          IOBuffer[offset++] = (SBYTE) sord[whichsord].where;
  4848.     }
  4849.     for (whichcountry = 0; whichcountry <= 35; whichcountry++)
  4850.     {   IOBuffer[offset++] = (SBYTE) world[whichcountry].hero;
  4851.         IOBuffer[offset++] = (SBYTE) world[whichcountry].is;
  4852.     }
  4853.  
  4854.     if (Write(FileHandle, IOBuffer, offset) != offset)
  4855.     {   Close(FileHandle);
  4856.         // FileHandle = NULL;
  4857.         strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_CANT_WRITE_TO, "Can't write to"));
  4858.         strcat(saystring, " ");
  4859.         strcat(saystring, newpathname);
  4860.         strcat(saystring, "!");
  4861.         say(LOWER);
  4862.         anykey();
  4863.         return;
  4864.     }
  4865.  
  4866.     /* write version string */
  4867.     Write(FileHandle, VERSION, strlen(VERSION));
  4868.  
  4869.     Close(FileHandle);
  4870.     // FileHandle = NULL;
  4871.  
  4872.     strcpy(pathname, newpathname);
  4873.  
  4874.     strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_SAVED, "Saved"));
  4875.     strcat(saystring, " ");
  4876.     strcat(saystring, pathname);
  4877.     strcat(saystring, ".");
  4878.     say(LOWER);
  4879.     // no need for anykey(), as there is one when we return anyway.
  4880. }
  4881.  
  4882. MODULE SLONG odin_tyr(SLONG whichhero, FLAG attacking)
  4883. {   SLONG whichjarl, whichprayer;
  4884.     SLONG adjustment = 0;
  4885.  
  4886.     if (hero[whichhero].god == ODIN)
  4887.     {   hero[whichhero].god = -1;
  4888.         whichprayer = d6();
  4889.         strcpy(saystring, "Odin");
  4890.  
  4891.         if (whichprayer == 1)
  4892.         {   adjustment = -3;
  4893.  
  4894.             strcat(saystring, " ");
  4895.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO, "aids hero"));
  4896.             strcat(saystring, " ");
  4897.             strcat(saystring, hero[whichhero].name);
  4898.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_E_B_A_3_T_T_S, "'s enemy by adding 3 to their strength"));
  4899.             strcat(saystring, ".");
  4900.         } elif (whichprayer == 2)
  4901.         {   adjustment = -1;
  4902.  
  4903.             strcat(saystring, " ");
  4904.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_SENDS_A_WOLF_TO_AID_HERO, "sends a wolf to aid hero"));
  4905.             strcat(saystring, " ");
  4906.             strcat(saystring, hero[whichhero].name);
  4907.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_ENEMY, "'s enemy"));
  4908.             strcat(saystring, ".");
  4909.         } elif (whichprayer == 3)
  4910.         {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_R_A_S_B_H_T_O_T_B, "'s ravens are sent by him to observe the battle"));
  4911.             strcat(saystring, ".");
  4912.         } elif (whichprayer == 4)
  4913.         {   adjustment = 1;
  4914.  
  4915.             strcat(saystring, " ");
  4916.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_SENDS_A_WOLF_TO_AID_HERO, "sends a wolf to aid hero"));
  4917.             strcat(saystring, " ");
  4918.             strcat(saystring, hero[whichhero].name);
  4919.             strcat(saystring, ".");
  4920.         } elif (whichprayer == 5)
  4921.         {   adjustment = 3;
  4922.  
  4923.             strcat(saystring, " ");
  4924.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO, "aids hero"));
  4925.             strcat(saystring, " ");
  4926.             strcat(saystring, hero[whichhero].name);
  4927.             strcat(saystring, " ");
  4928.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_BY_ADDING_3_TO_HIS_STRENGTH, "by adding 3 to his strength"));
  4929.             strcat(saystring, ".");
  4930.         } else
  4931.         {   // assert(whichprayer == 6);
  4932.  
  4933.             adjustment = 5;
  4934.             hero[whichhero].glory += 3;
  4935.  
  4936.             strcat(saystring, " ");
  4937.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_INTERVENES_PERSONALLY, "intervenes personally"));
  4938.             strcat(saystring, ".");
  4939.         }
  4940.         say(LOWER);
  4941.         anykey();
  4942.     } elif (hero[whichhero].god == TYR)
  4943.     {   hero[whichhero].god = -1;
  4944.         whichprayer = d6();
  4945.         strcpy(saystring, "Tyr ");
  4946.  
  4947.         if (whichprayer == 1)
  4948.         {   adjustment = -1;
  4949.  
  4950.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO, "aids hero"));
  4951.             strcat(saystring, " ");
  4952.             strcat(saystring, hero[whichhero].name);
  4953.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_E_B_A_1_T_T_S, "'s enemy by adding 1 to their strength"));
  4954.             strcat(saystring, ".");
  4955.         } elif (whichprayer == 2 || whichprayer == 3)
  4956.         {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_D_T_T_F_I_B_F, "decides that the fight is balanced fairly"));
  4957.             strcat(saystring, ".");
  4958.         } elif (whichprayer == 4)
  4959.         {   adjustment = 1;
  4960.  
  4961.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO, "aids hero"));
  4962.             strcat(saystring, " ");
  4963.             strcat(saystring, hero[whichhero].name);
  4964.             strcat(saystring, " ");
  4965.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_BY_ADDING_1_TO_HIS_STRENGTH, "by adding 1 to his strength"));
  4966.             strcat(saystring, ".");
  4967.         } elif (whichprayer == 5)
  4968.         {   adjustment = 2;
  4969.  
  4970.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO, "aids hero"));
  4971.             strcat(saystring, " ");
  4972.             strcat(saystring, hero[whichhero].name);
  4973.             strcat(saystring, " ");
  4974.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_BY_ADDING_2_TO_HIS_STRENGTH, "by adding 2 to his strength"));
  4975.             strcat(saystring, ".");
  4976.         } else
  4977.         {   assert(whichprayer == 6);
  4978.  
  4979.             adjustment = 1; // for the hero himself
  4980.             if (attacking)
  4981.             {   for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  4982.                 {   if (jarl[whichjarl].attacking)
  4983.                     {   adjustment++;
  4984.             }   }   }
  4985.             else
  4986.             {   for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  4987.                 {   if (jarl[whichjarl].defending)
  4988.                     {   adjustment++;
  4989.             }   }   }
  4990.  
  4991.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_AIDS_HERO, "aids hero"));
  4992.             strcat(saystring, " ");
  4993.             strcat(saystring, hero[whichhero].name);
  4994.             strcat(saystring, " ");
  4995.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_B_A_1_T_T_S_O_E_P_O_H_S, "by adding 1 to the strength of each person on his side"));
  4996.             strcat(saystring, ".");
  4997.         }
  4998.         say(LOWER);
  4999.         anykey();
  5000.     }
  5001.     return(adjustment);
  5002. }
  5003.  
  5004. MODULE void pray(SLONG whichhero)
  5005. {   SLONG decision;
  5006.  
  5007.     decision = d6();
  5008.     if (decision == 1 || (hero[whichhero].rune == AMSIR && decision == 2))
  5009.     {   gods(whichhero);
  5010. }   }
  5011.  
  5012. MODULE void amiga_rout(SLONG routedtype, SLONG routed)
  5013. {   SLONG decision, whichmove, moves;
  5014.     FLAG freemove;
  5015.  
  5016.     if (routedtype == HERO)
  5017.     {   hero[routed].routed = TRUE;
  5018.     } elif (routedtype == JARL)
  5019.     {   jarl[routed].routed = TRUE;
  5020.     }
  5021.  
  5022.     moves = getmoves(routedtype, routed, FALSE);
  5023.     if (moves < 1)
  5024.     {   return;
  5025.     }
  5026.  
  5027.     if (routedtype == HERO || routedtype == JARL)
  5028.     {   saywho(routedtype, routed, FALSE, FALSE);
  5029.     } else
  5030.     {   // assert(routedtype == MONSTER);
  5031.         strcpy(saystring, monstertypes[monster[routed].species]);
  5032.         strcat(saystring, " ");
  5033.         strcat(saystring, monster[routed].name);
  5034.         strcat(saystring, " ");
  5035.     }
  5036.  
  5037.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IS_BEING_ROUTED, "is being routed"));
  5038.     strcat(saystring, "...");
  5039.     say(LOWER);
  5040.  
  5041.     if (routedtype == HERO)
  5042.     {   freemove = FALSE;
  5043.         select_hero(routed, TRUE);
  5044.         for (whichmove = 1; whichmove <= moves; whichmove++)
  5045.         {   do
  5046.             {   decision = rand() % (CONNECTIONS + 1);
  5047.             } while (world[hero[routed].where].connection[decision] == -1);
  5048.             if
  5049.             (   hero[routed].sea == BAD
  5050.              && (   world[world[hero[routed].where].connection[decision]].type == SEA
  5051.                  || world[world[hero[routed].where].connection[decision]].type == ISLE
  5052.             )   )
  5053.             {   whichmove--;
  5054.             } else
  5055.             {   unslot_hero(routed);
  5056.                 hero[routed].where = world[hero[routed].where].connection[decision];
  5057.                 move_hero(routed, TRUE);
  5058.                 if (hero[routed].sea == GOOD)
  5059.                 {   if (!freemove)
  5060.                     {   if
  5061.                         (   world[hero[routed].where].type == SEA
  5062.                          || world[hero[routed].where].type == ISLE
  5063.                         )
  5064.                         {   freemove = TRUE;
  5065.                     }   }
  5066.                     else
  5067.                     {   if
  5068.                         (   world[hero[routed].where].type == LAND
  5069.                         )
  5070.                         {   freemove = FALSE;
  5071.                         } else
  5072.                         {   whichmove--;
  5073.         }   }   }   }   }
  5074.         deselect_hero(routed, TRUE);
  5075.     } elif (routedtype == JARL)
  5076.     {   select_jarl(routed, TRUE);
  5077.         for (whichmove = 1; whichmove <= moves; whichmove++)
  5078.         {   do
  5079.             {   decision = rand() % (CONNECTIONS + 1);
  5080.             } while (world[jarl[routed].where].connection[decision] == -1);
  5081.             if
  5082.             (   jarl[routed].sea == BAD
  5083.              && (   world[world[jarl[routed].where].connection[decision]].type == SEA
  5084.                  || world[world[jarl[routed].where].connection[decision]].type == ISLE
  5085.             )   )
  5086.             {   whichmove--;
  5087.             } else
  5088.             {   unslot_jarl(routed);
  5089.                 jarl[routed].where = world[jarl[routed].where].connection[decision];
  5090.                 move_jarl(routed, TRUE);
  5091.         }   }
  5092.         deselect_jarl(routed, TRUE);
  5093.     } elif (routedtype == MONSTER)
  5094.     {   // select_monster(routed);
  5095.         for (whichmove = 1; whichmove <= moves; whichmove++)
  5096.         {   do
  5097.             {   decision = rand() % (CONNECTIONS + 1);
  5098.             } while (world[monster[routed].where].connection[decision] == -1);
  5099.             if
  5100.             (   monster[routed].sea == BAD
  5101.              && (   world[world[monster[routed].where].connection[decision]].type == SEA
  5102.                  || world[world[monster[routed].where].connection[decision]].type == ISLE
  5103.             )   )
  5104.             {   whichmove--;
  5105.             } else
  5106.             {   unslot_monster(routed);
  5107.                 monster[routed].where = world[monster[routed].where].connection[decision];
  5108.                 move_monster(routed, TRUE);
  5109.         }   }
  5110.         // deselect_monster(routed);
  5111. }   }
  5112.  
  5113. MODULE void human_rout(SLONG routedtype, SLONG routed, SLONG routerhero)
  5114. {   SLONG country,
  5115.           oldcountry = -1,
  5116.           moves,
  5117.           whichconnection,
  5118.           whichmove;
  5119.     FLAG  legal, freemove;
  5120.  
  5121.     moves = getmoves(routedtype, routed, FALSE);
  5122.  
  5123.     if (moves == 0)
  5124.     {   return;
  5125.     }
  5126.  
  5127.     if (routedtype == HERO)
  5128.     {   select_hero(routed, TRUE);
  5129.         oldcountry = hero[routed].where;
  5130.     } elif (routedtype == JARL)
  5131.     {   select_jarl(routed, TRUE);
  5132.         oldcountry = jarl[routed].where;
  5133.     } elif (routedtype == MONSTER)
  5134.     {   // select_monster(routed);
  5135.         oldcountry = monster[routed].where;
  5136.     }
  5137.  
  5138.     whichmove = 1;
  5139.     freemove = FALSE;
  5140.     do
  5141.     {   saywho(HERO, routerhero, TRUE, FALSE);
  5142.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_ROUT, "rout"));
  5143.         strcat(saystring, " ");
  5144.         stcl_d(numberstring, whichmove);
  5145.         strcat(saystring, numberstring);
  5146.         strcat(saystring, " ");
  5147.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_OF, "of"));
  5148.         strcat(saystring, " ");
  5149.         stcl_d(numberstring, moves);
  5150.         strcat(saystring, numberstring);
  5151.         strcat(saystring, " ");
  5152.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FOR, "for"));
  5153.  
  5154.         if (routedtype == HERO || routedtype == JARL)
  5155.         {   saywho(routedtype, routed, FALSE, TRUE);
  5156.         } else
  5157.         {   // assert(routedtype == MONSTER);
  5158.             strcat(saystring, " ");
  5159.             strcat(saystring, monstertypes[monster[routed].species]);
  5160.             strcat(saystring, " ");
  5161.             strcat(saystring, monster[routed].name);
  5162.         }
  5163.         strcat(saystring, "?");
  5164.         say(LOWER);
  5165.  
  5166.         do
  5167.         {   country = getevent(COUNTRY, NULL);
  5168.         } while ((country < -3 || country > 65) || country == -1);
  5169.         if (country == -3)
  5170.         {   break;
  5171.         } elif (country == -2)
  5172.         {   whichmove = 1;
  5173.             if (routedtype == HERO)
  5174.             {   unslot_hero(routed);
  5175.                 hero[routed].where = oldcountry;
  5176.                 move_hero(routed, TRUE);
  5177.                 freemove = FALSE;
  5178.             } elif (routedtype == JARL)
  5179.             {   unslot_jarl(routed);
  5180.                 jarl[routed].where = oldcountry;
  5181.                 move_jarl(routed, TRUE);
  5182.             } else
  5183.             {   // assert(routedtype == MONSTER);
  5184.                 unslot_monster(routed);
  5185.                 monster[routed].where = oldcountry;
  5186.                 move_monster(routed, TRUE);
  5187.         }   }
  5188.         else
  5189.         {   legal = FALSE;
  5190.             for (whichconnection = 0; whichconnection <= CONNECTIONS; whichconnection++)
  5191.             {   if
  5192.                 (   (routedtype == HERO    && world[hero[routed].where].connection[whichconnection] == country)
  5193.                  || (routedtype == JARL    && world[jarl[routed].where].connection[whichconnection] == country)
  5194.                  || (routedtype == MONSTER && world[monster[routed].where].connection[whichconnection] == country)
  5195.                 )
  5196.                 {   legal = TRUE;
  5197.                     break; // for speed
  5198.             }   }
  5199.             if (legal)
  5200.             {   if (routedtype == HERO)
  5201.                 {   if
  5202.                     (   hero[routed].sea == BAD
  5203.                      && (   world[country].type == SEA
  5204.                          || world[country].type == ISLE
  5205.                     )   )
  5206.                     {   legal = FALSE;
  5207.                         saywho(HERO, routed, FALSE, FALSE);
  5208.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_M_N_T_B_S_T_T, "may not travel by sea this turn"));
  5209.                         strcat(saystring, ".");
  5210.                         say(LOWER);
  5211.                         anykey();
  5212.                 }   }
  5213.                 elif (routedtype == JARL)
  5214.                 {   if
  5215.                     (   jarl[routed].sea == BAD
  5216.                      && (   world[country].type == SEA
  5217.                          || world[country].type == ISLE
  5218.                     )   )
  5219.                     {   legal = FALSE;
  5220.                         saywho(JARL, routed, FALSE, FALSE);
  5221.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_M_N_T_B_S_T_T, "may not travel by sea this turn"));
  5222.                         strcat(saystring, ".");
  5223.                         say(LOWER);
  5224.                         anykey();
  5225.                 }   }
  5226.                 elif (routedtype == MONSTER)
  5227.                 {   if
  5228.                     (   monster[routed].sea == BAD
  5229.                      && (   world[country].type == SEA
  5230.                          || world[country].type == ISLE
  5231.                     )   )
  5232.                     {   legal = FALSE;
  5233.                         strcat(saystring, monstertypes[monster[routed].species]);
  5234.                         strcat(saystring, " ");
  5235.                         strcat(saystring, monster[routed].name);
  5236.                         strcat(saystring, " ");
  5237.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_M_N_T_B_S_T_T, "may not travel by sea this turn"));
  5238.                         strcat(saystring, ".");
  5239.                         say(LOWER);
  5240.                         anykey();
  5241.             }   }   }
  5242.             if (legal)
  5243.             {   if (routedtype == HERO)
  5244.                 {   unslot_hero(routed);
  5245.                     hero[routed].where = country;
  5246.                     move_hero(routed, TRUE);
  5247.  
  5248.                     if (hero[routed].sea == GOOD)
  5249.                     {   if (!freemove)
  5250.                         {   if
  5251.                             (   world[hero[routed].where].type == SEA
  5252.                              || world[hero[routed].where].type == ISLE
  5253.                             )
  5254.                             {   freemove = TRUE;
  5255.                             }
  5256.                             whichmove++;
  5257.                         } else
  5258.                         {   if
  5259.                             (   world[hero[routed].where].type == LAND
  5260.                             )
  5261.                             {   freemove = FALSE;
  5262.                                 whichmove++;
  5263.                 }   }   }   }
  5264.                 elif (routedtype == JARL)
  5265.                 {   unslot_jarl(routed);
  5266.                     jarl[routed].where = country;
  5267.                     move_jarl(routed, TRUE);
  5268.                 } else
  5269.                 {   // assert(routedtype == MONSTER);
  5270.                     unslot_monster(routed);
  5271.                     monster[routed].where = country;
  5272.                     move_monster(routed, TRUE);
  5273.                 }
  5274.                 whichmove++;
  5275.             } else
  5276.             {   ; // DisplayBeep(ScreenPtr);
  5277.         }   }
  5278.     } while (whichmove <= moves);
  5279.  
  5280.     if (routedtype == HERO)
  5281.     {   deselect_hero(routed, TRUE);
  5282.     } elif (routedtype == JARL)
  5283.     {   deselect_jarl(routed, TRUE);
  5284. }   }
  5285.  
  5286. MODULE SLONG getmoves(SLONG countertype, SLONG whichcounter, FLAG freyfaxi)
  5287. {   SLONG moves;
  5288.  
  5289.     if (countertype == HERO)
  5290.     {   moves = hero[whichcounter].moves;
  5291.     } elif (countertype == MONSTER)
  5292.     {   // assert(!freyfaxi);
  5293.         moves = monster[whichcounter].moves;
  5294.     } else
  5295.     {   assert(countertype == JARL);
  5296.         moves = jarl[whichcounter].moves;
  5297.     }
  5298.  
  5299.     if (freyfaxi)
  5300.     {   moves *= 2;
  5301.     }
  5302.  
  5303.     if
  5304.     (   countertype != MONSTER // so dragon's don't use magic treasures
  5305.      && treasure[MAGICSHIRT].possessortype == countertype
  5306.      && treasure[MAGICSHIRT].possessor     == whichcounter
  5307.     )
  5308.     {   // assert(treasure[MAGICSHIRT].where == -1);
  5309.         moves++;
  5310.     }
  5311.  
  5312.     if (countertype == HERO && hero[whichcounter].rune == EON)
  5313.     {   moves++;
  5314.     }
  5315.  
  5316.     if
  5317.     (   (countertype == HERO && hero[whichcounter].loseturn)
  5318.      || (countertype == JARL && jarl[whichcounter].loseturn)
  5319.     )
  5320.     {   moves = 0;
  5321.     }
  5322.  
  5323.     /* If you are stuck at sea or on an island, and can't travel
  5324.        by sea, then you can't move at all that turn. */
  5325.     if
  5326.     (   countertype == HERO
  5327.      && hero[whichcounter].sea == BAD
  5328.      && (   world[hero[whichcounter].where].type == SEA
  5329.          || world[hero[whichcounter].where].type == ISLE
  5330.     )   )
  5331.     {   moves = 0;
  5332.     } elif
  5333.     (   countertype == JARL
  5334.      && jarl[whichcounter].sea == BAD
  5335.      && (   world[jarl[whichcounter].where].type == SEA
  5336.          || world[jarl[whichcounter].where].type == ISLE
  5337.     )   )
  5338.     {   moves = 0;
  5339.     } elif
  5340.     (   countertype == MONSTER
  5341.      && monster[whichcounter].sea == BAD
  5342.      && (   world[monster[whichcounter].where].type == SEA
  5343.          || world[monster[whichcounter].where].type == ISLE
  5344.     )   )
  5345.     {   moves = 0;
  5346.     }
  5347.  
  5348.     return(moves);
  5349. }
  5350.  
  5351. MODULE void faxi_disappear(void)
  5352. {   if (faxirides == 0) // faxi disappears
  5353.     {   treasure[FREYFAXI].possessortype = -1; // noone
  5354.         treasure[FREYFAXI].possessor     = -1; // noone
  5355.         treasure[FREYFAXI].where         = -1; // nowhere
  5356.         // frey faxi won't be on the board at the moment anyway
  5357.         faxirides = -1; // so it only disappears once
  5358. }   }
  5359.  
  5360. MODULE void thor(SLONG whichhero)
  5361. {   SLONG whichprayer;
  5362.  
  5363.     if (hero[whichhero].god == THOR)
  5364.     {   hero[whichhero].god = -1;
  5365.         whichprayer = d6();
  5366.         strcpy(saystring, "Thor ");
  5367.  
  5368.         if (whichprayer >= 1 && whichprayer <= 3)
  5369.         {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_DECIDES_THAT_HERO, "decides that hero"));
  5370.             strcat(saystring, " ");
  5371.             strcat(saystring, hero[whichhero].name);
  5372.             strcat(saystring, " ");
  5373.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_DESERVES_NO_REWARD, "deserves no reward"));
  5374.             strcat(saystring, ".");
  5375.         } elif (whichprayer == 4 || whichprayer == 5)
  5376.         {   hero[whichhero].glory++;
  5377.  
  5378.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_REWARDS_HERO, "rewards hero"));
  5379.             strcat(saystring, " ");
  5380.             strcat(saystring, hero[whichhero].name);
  5381.             strcat(saystring, " ");
  5382.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_B_S_T_H_G_1_G, "by speaking to him, granting 1 glory"));
  5383.             strcat(saystring, ".");
  5384.         } else
  5385.         {   // assert(whichprayer == 6);
  5386.  
  5387.             hero[whichhero].glory += 2;
  5388.  
  5389.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HONOURS_HERO, "honours hero"));
  5390.             strcat(saystring, " ");
  5391.             strcat(saystring, hero[whichhero].name);
  5392.             strcat(saystring, " ");
  5393.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_B_E_W_H_G_2_G, "by eating with him, granting 2 glory"));
  5394.             strcat(saystring, ".");
  5395.         }
  5396.         say(LOWER);
  5397.         anykey();
  5398. }   }
  5399.  
  5400. MODULE void dospell(SLONG spell, SLONG caster)
  5401. {   SLONG whichhero, whichjarl, whichmonster;
  5402.  
  5403.     if (spell == HAGALL || spell == JARA || d6() <= 3) // if it's a spell which doesn't have a saving throw, or the saving throw is missed
  5404.     {   strcat(saystring, ".");
  5405.         say(LOWER);
  5406.         anykey();
  5407.  
  5408.         for (whichhero = 0; whichhero <= HEROES; whichhero++)
  5409.         {   if
  5410.             (   hero[whichhero].control != NONE
  5411.              && hero[whichhero].alive
  5412.              && hero[whichhero].where == monster[caster].where
  5413.             )
  5414.             {   if (hero[whichhero].rune == SYGIL && d6() <= 3)
  5415.                 {   strcpy(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO, "Hero"));
  5416.                     strcat(saystring, " ");
  5417.                     strcat(saystring, hero[whichhero].name);
  5418.                     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_RUNE_PROTECTS_HIM, "'s rune protects him"));
  5419.                     strcat(saystring, ".");
  5420.                     say(LOWER);
  5421.                     anykey();
  5422.                 } else
  5423.                 {   if (spell == HAGALL)
  5424.                     {   hero[whichhero].hagall = TRUE;
  5425.                         hero[whichhero].sea    = BAD;
  5426.                     } elif (spell == JARA)
  5427.                     {   hero[whichhero].loseturn = TRUE;
  5428.                     } elif (spell == NIED)
  5429.                     {   hero[whichhero].loseturn = TRUE;
  5430.                         hero[whichhero].attacking = FALSE;
  5431.                         deselect_hero(whichhero, TRUE);
  5432.                     } elif (spell == WYNN)
  5433.                     {   hero[whichhero].glory -= 2;
  5434.                         if (hero[whichhero].glory < 0)
  5435.                         {   hero[whichhero].glory = 0;
  5436.                         }
  5437.                         amiga_rout(HERO, whichhero);
  5438.                         hero[whichhero].attacking = FALSE;
  5439.                         deselect_hero(whichhero, TRUE);
  5440.                     } elif (spell == YR)
  5441.                     {   wound(MONSTER, caster, -1, HERO, whichhero, whichhero);
  5442.                         hero[whichhero].attacking = FALSE;
  5443.                         deselect_hero(whichhero, TRUE);
  5444.         }   }   }   }
  5445.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  5446.         {   if
  5447.             (   jarl[whichjarl].alive
  5448.              && jarl[whichjarl].where == monster[caster].where
  5449.             )
  5450.             {   if (spell == HAGALL)
  5451.                 {   jarl[whichjarl].hagall = TRUE;
  5452.                     jarl[whichjarl].sea    = BAD;
  5453.                 } elif (spell == JARA)
  5454.                 {   jarl[whichjarl].loseturn = TRUE;
  5455.                 } elif (spell == NIED)
  5456.                 {   jarl[whichjarl].loseturn = TRUE;
  5457.                     jarl[whichjarl].attacking = FALSE;
  5458.                     deselect_jarl(whichjarl, TRUE);
  5459.                 } elif (spell == WYNN)
  5460.                 {   amiga_rout(JARL, whichjarl);
  5461.                     jarl[whichjarl].attacking = FALSE;
  5462.                     deselect_jarl(whichjarl, TRUE);
  5463.                 } elif (spell == YR)
  5464.                 {   if (jarl[whichjarl].face == FACEUP)
  5465.                     {   wound(MONSTER, caster, -1, JARL, whichjarl, jarl[whichjarl].hero);
  5466.                         jarl[whichjarl].attacking = FALSE;
  5467.                         deselect_jarl(whichjarl, TRUE);
  5468.         }   }   }   }
  5469.         
  5470.         if (spell == HAGALL)
  5471.         {   for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  5472.             {   if
  5473.                 (   monster[whichmonster].alive
  5474.                  && monster[whichmonster].where == monster[caster].where
  5475.                 )
  5476.                 {   monster[whichmonster].hagall = TRUE;
  5477.                     monster[whichmonster].sea    = BAD;
  5478.     }   }   }   }
  5479.     else
  5480.     {   strcat(saystring, ", ");
  5481.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_BUT_IT_FIZZLES, "but it fizzles"));
  5482.         strcat(saystring, "!");
  5483.         say(LOWER);
  5484.         anykey();
  5485. }   }
  5486.  
  5487. MODULE void cast(SLONG caster, SLONG whichspell)
  5488. {   strcpy(saystring, monstertypes[monster[caster].species]);
  5489.     strcat(saystring, " ");
  5490.     strcat(saystring, monster[caster].name);
  5491.     strcat(saystring, " ");
  5492.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CASTS, "casts"));
  5493.     strcat(saystring, " ");
  5494.  
  5495.     switch(whichspell)
  5496.     {
  5497.     case HAGALL:
  5498.         strcat(saystring, "Hagall (");
  5499.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HAIL_SLOW, "hail/slow"));
  5500.         strcat(saystring, ")");
  5501.  
  5502.         dospell(HAGALL, caster);
  5503.     break;
  5504.     case IS:
  5505.         world[monster[caster].where].is = TRUE;
  5506.         darken();
  5507.  
  5508.         strcat(saystring, "Is (");
  5509.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_ICE, "ice"));
  5510.         strcat(saystring, ").");
  5511.         say(LOWER);
  5512.         anykey();
  5513.     break;
  5514.     case JARA:
  5515.         strcat(saystring, "Jara (");
  5516.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_LOSE_NEXT_TURN, "lose next turn"));
  5517.         strcat(saystring, ")");
  5518.  
  5519.         dospell(JARA, caster);
  5520.     break;
  5521.     case NIED:
  5522.         strcat(saystring, "Nied (");
  5523.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_N_R_A_L_N_T, "no result and lose next turn"));
  5524.         strcat(saystring, ")");
  5525.  
  5526.         dospell(NIED, caster);
  5527.     break;
  5528.     case WYNN:
  5529.         strcat(saystring, "Wynn (");
  5530.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_FLEEING, "fleeing"));
  5531.         strcat(saystring, ")");
  5532.  
  5533.         dospell(WYNN, caster);
  5534.     break;
  5535.     case YR:
  5536.         strcat(saystring, "Yr (");
  5537.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_WOUNDING, "wounding"));
  5538.         strcat(saystring, ")");
  5539.  
  5540.         dospell(YR, caster);
  5541.     break;
  5542.     default:
  5543.         // assert(0);
  5544.     break;
  5545. }   }
  5546.  
  5547. MODULE void darken(void)
  5548. {   SLONG whichcountry, colour;
  5549.  
  5550.     for (whichcountry = 0; whichcountry <= 35; whichcountry++)
  5551.     {   if (whichcountry >= 9 && whichcountry <= 11)
  5552.         {   colour = whichcountry + 80;
  5553.         } else
  5554.         {   colour = whichcountry + 8;
  5555.         }
  5556.         if (world[whichcountry].is)
  5557.         {   SetRGB4(&ScreenPtr->ViewPort, colour, 12, 12, 12); // light grey ice
  5558.         } elif (world[whichcountry].hero != -1)
  5559.         {   SetRGB4
  5560.             (   &ScreenPtr->ViewPort,
  5561.                 colour,
  5562.                 herocolour[world[whichcountry].hero].red,
  5563.                 herocolour[world[whichcountry].hero].green,
  5564.                 herocolour[world[whichcountry].hero].blue
  5565.             );
  5566.         } else
  5567.         {   SetRGB4
  5568.             (   &ScreenPtr->ViewPort,
  5569.                 colour,
  5570.                 taxcolours[world[whichcountry].tax].red,
  5571.                 taxcolours[world[whichcountry].tax].green,
  5572.                 taxcolours[world[whichcountry].tax].blue
  5573.             );
  5574. }   }   }
  5575.  
  5576. MODULE SLONG checkcountry(WORD mousex, WORD mousey)
  5577. {   SLONG country;
  5578.  
  5579.     country = ReadPixel(MainWindowPtr->RPort, mousex, mousey);
  5580.     if (country == 80 || country == 81 || country == 91)
  5581.     {   country = 11; // Scandia
  5582.     } elif (country == 82 || country == 83)
  5583.     {   country = 30; // Pictland
  5584.     } elif (country == 84 || country == 85)
  5585.     {   country = 31; // Hebrides
  5586.     } elif (country == 89)
  5587.     {   country =  9; // Suder Gotland
  5588.     } elif (country == 90)
  5589.     {   country = 10; // Juteland
  5590.     } else
  5591.     {   country -= 8;
  5592.     }
  5593.  
  5594.     return(country);
  5595. }
  5596.  
  5597. MODULE void infowindow(SLONG countertype, SLONG whichcounter)
  5598. {   SLONG                lines,
  5599.                          leftlines     = 0,
  5600.                          rightlines    = 0,
  5601.                          oldwhichline,
  5602.                          whichline,
  5603.                          whichcountry,
  5604.                          whichjarl,
  5605.                          whichhero,
  5606.                          whichtreasure,
  5607.                          whichsord,
  5608.                          wide,
  5609.                          whichmonster;
  5610.     FLAG                 counterrow = FALSE,
  5611.                          done       = FALSE,
  5612.                          ok;
  5613.     ULONG                class;
  5614.     UWORD                code, qual;
  5615.     struct IntuiMessage* MsgPtr;
  5616.  
  5617.     if (countertype == HERO)
  5618.     {   strcpy(line[LEFTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_HERO_NAME, "Hero Name"));
  5619.         strcat(line[LEFTSIDE][0], ":");
  5620.         pad(line[LEFTSIDE][0]);
  5621.         strcat(line[LEFTSIDE][0], hero[whichcounter].name);
  5622.  
  5623.         strcpy(line[LEFTSIDE][1], GetCatalogStr(li.li_Catalog, MSG_CONTROL, "Control"));
  5624.         strcat(line[LEFTSIDE][1], ":");
  5625.         pad(line[LEFTSIDE][1]);
  5626.         if (hero[whichcounter].control == HUMAN)
  5627.         {   strcat(line[LEFTSIDE][1], GetCatalogStr(li.li_Catalog, MSG_HUMAN, "Human"));
  5628.         } else
  5629.         {   // assert(hero[whichcounter].control == AMIGA);
  5630.             strcat(line[LEFTSIDE][1], "Amiga");
  5631.         }
  5632.         
  5633.         strcpy(line[LEFTSIDE][2], GetCatalogStr(li.li_Catalog, MSG_COMBAT_STRENGTH, "Combat Strength"));
  5634.         strcat(line[LEFTSIDE][2], ":");
  5635.         pad(line[LEFTSIDE][2]);
  5636.         stcl_d(numberstring, hero[whichcounter].strength);
  5637.         strcat(line[LEFTSIDE][2], numberstring);
  5638.         
  5639.         strcpy(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_MOVEMENT_FACTOR, "Movement Factor"));
  5640.         strcat(line[LEFTSIDE][3], ":");
  5641.         pad(line[LEFTSIDE][3]);
  5642.         stcl_d(numberstring, hero[whichcounter].moves);
  5643.         strcat(line[LEFTSIDE][3], numberstring);
  5644.         
  5645.         strcpy(line[LEFTSIDE][4], GetCatalogStr(li.li_Catalog, MSG_GLORY, "Glory"));
  5646.         strcat(line[LEFTSIDE][4], ":");
  5647.         pad(line[LEFTSIDE][4]);
  5648.         stcl_d(numberstring, hero[whichcounter].glory);
  5649.         strcat(line[LEFTSIDE][4], numberstring);
  5650.         
  5651.         strcpy(line[LEFTSIDE][5], GetCatalogStr(li.li_Catalog, MSG_LUCK, "Luck"));
  5652.         strcat(line[LEFTSIDE][5], ":");
  5653.         pad(line[LEFTSIDE][5]);
  5654.         stcl_d(numberstring, hero[whichcounter].luck);
  5655.         strcat(line[LEFTSIDE][5], numberstring);
  5656.         
  5657.         strcpy(line[LEFTSIDE][6], GetCatalogStr(li.li_Catalog, MSG_WEALTH, "Wealth"));
  5658.         strcat(line[LEFTSIDE][6], ":");
  5659.         pad(line[LEFTSIDE][6]);
  5660.         stcl_d(numberstring, hero[whichcounter].wealth);
  5661.         strcat(line[LEFTSIDE][6], numberstring);
  5662.  
  5663.         print_location(hero[whichcounter].where, 7);
  5664.  
  5665.         strcpy(line[LEFTSIDE][8], GetCatalogStr(li.li_Catalog, MSG_HOMELAND, "Homeland"));
  5666.         strcat(line[LEFTSIDE][8], ":");
  5667.         pad(line[LEFTSIDE][8]);
  5668.         strcat(line[LEFTSIDE][8], world[hero[whichcounter].homewhere].name);
  5669.         strcat(line[LEFTSIDE][8], " (");
  5670.         stcl_d(numberstring, world[hero[whichcounter].homewhere].tax);
  5671.         strcat(line[LEFTSIDE][8], numberstring);
  5672.         strcat(line[LEFTSIDE][8], ")");
  5673.         
  5674.         strcpy(line[LEFTSIDE][9], GetCatalogStr(li.li_Catalog, MSG_MAIDENS, "Maidens"));
  5675.         strcat(line[LEFTSIDE][9], ":");
  5676.         pad(line[LEFTSIDE][9]);
  5677.         stcl_d(numberstring, hero[whichcounter].maidens);
  5678.         strcat(line[LEFTSIDE][9], numberstring);
  5679.       
  5680.         strcpy(line[LEFTSIDE][10], GetCatalogStr(li.li_Catalog, MSG_RUNE, "Rune"));
  5681.         strcat(line[LEFTSIDE][10], ":");
  5682.         pad(line[LEFTSIDE][10]);
  5683.         if (hero[whichcounter].rune == -1)
  5684.         {   strcat(line[LEFTSIDE][10], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
  5685.         } else
  5686.         {   strcat(line[LEFTSIDE][10], runename[hero[whichcounter].rune]);
  5687.         }
  5688.  
  5689.         strcpy(line[LEFTSIDE][11], GetCatalogStr(li.li_Catalog, MSG_SWORD, "Sword"));
  5690.         strcat(line[LEFTSIDE][11], ":");
  5691.         pad(line[LEFTSIDE][11]);
  5692.         ok = FALSE;
  5693.         for (whichsord = 0; whichsord <= SORDS; whichsord++)
  5694.         {   if
  5695.             (   sord[whichsord].possessortype == HERO
  5696.              && sord[whichsord].possessor == whichcounter
  5697.             )
  5698.             {   ok = TRUE;
  5699.                 counterrow = TRUE;
  5700.                 strcat(line[LEFTSIDE][11], sord[whichsord].name);
  5701.                 break; // for speed
  5702.         }   }
  5703.         if (!ok)
  5704.         {   strcat(line[LEFTSIDE][11], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
  5705.         }
  5706.  
  5707.         strcpy(line[LEFTSIDE][12], GetCatalogStr(li.li_Catalog, MSG_WOUNDED, "Wounded"));
  5708.         strcat(line[LEFTSIDE][12], "?");
  5709.         pad(line[LEFTSIDE][12]);
  5710.         if (hero[whichcounter].wounded)
  5711.         {   strcat(line[LEFTSIDE][12], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
  5712.         } else
  5713.         {   strcat(line[LEFTSIDE][12], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
  5714.         }
  5715.  
  5716.         print_paralyzed(hero[whichcounter].loseturn, 13);
  5717.  
  5718.         print_hagall(hero[whichcounter].hagall, 14);
  5719.  
  5720.         print_sea(hero[whichcounter].sea, 15);
  5721.  
  5722.         print_routed(hero[whichcounter].routed, 16);
  5723.  
  5724.         leftlines = 17; // counting from 1
  5725.  
  5726.         strcpy(line[RIGHTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_RECRUITED_JARLS, "Recruited Jarls"));
  5727.         strcat(line[RIGHTSIDE][0], ":");
  5728.  
  5729.         whichline = oldwhichline = 1; // whichline always points to the NEXT line.
  5730.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  5731.         {   if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichcounter)
  5732.             {   strcpy(line[RIGHTSIDE][whichline], " ");
  5733.                 strcat(line[RIGHTSIDE][whichline], jarl[whichjarl].name);
  5734.                 strcat(line[RIGHTSIDE][whichline], " (");
  5735.                 stcl_d(numberstring, jarl[whichjarl].strength);
  5736.                 strcat(line[RIGHTSIDE][whichline], numberstring);
  5737.                 strcat(line[RIGHTSIDE][whichline], "-");
  5738.                 stcl_d(numberstring, jarl[whichjarl].moves);
  5739.                 strcat(line[RIGHTSIDE][whichline], numberstring);
  5740.                 strcat(line[RIGHTSIDE][whichline], ")");
  5741.                 whichline++;
  5742.         }   }
  5743.         if (whichline == oldwhichline)
  5744.         {   strcpy(line[RIGHTSIDE][whichline], " ");
  5745.             strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
  5746.             whichline++;
  5747.         }
  5748.  
  5749.         strcpy(line[RIGHTSIDE][whichline], "");
  5750.         whichline++;
  5751.         strcpy(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_CONQUERED_KINGDOMS, "Conquered Kingdoms"));
  5752.         strcat(line[RIGHTSIDE][whichline], ":");
  5753.         whichline++;
  5754.  
  5755.         oldwhichline = whichline;
  5756.         for (whichcountry = 0; whichcountry <= 35; whichcountry++)
  5757.         {   if (world[whichcountry].hero == whichcounter)
  5758.             {   strcpy(line[RIGHTSIDE][whichline], " ");
  5759.                 strcat(line[RIGHTSIDE][whichline], world[whichcountry].name);
  5760.                 strcat(line[RIGHTSIDE][whichline], " (");
  5761.                 stcl_d(numberstring, world[whichcountry].tax);
  5762.                 strcat(line[RIGHTSIDE][whichline], numberstring);
  5763.                 strcat(line[RIGHTSIDE][whichline], ")");
  5764.                 whichline++;
  5765.         }   }
  5766.         if (whichline == oldwhichline)
  5767.         {   strcpy(line[RIGHTSIDE][whichline], " ");
  5768.             strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
  5769.             whichline++;
  5770.         }
  5771.  
  5772.         strcpy(line[RIGHTSIDE][whichline], "");
  5773.         whichline++;
  5774.         strcpy(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_MAGIC_TREASURES, "Magic Treasures"));
  5775.         strcat(line[RIGHTSIDE][whichline], ":");
  5776.         whichline++;
  5777.  
  5778.         oldwhichline = whichline;
  5779.         for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  5780.         {   if (treasure[whichtreasure].possessortype == HERO
  5781.              && treasure[whichtreasure].possessor     == whichcounter
  5782.             )
  5783.             {   counterrow = TRUE;
  5784.                 strcpy(line[RIGHTSIDE][whichline], " ");
  5785.                 strcat(line[RIGHTSIDE][whichline], treasure[whichtreasure].name);
  5786.                 if (whichtreasure == FREYFAXI)
  5787.                 {   strcat(line[RIGHTSIDE][whichline], " (");
  5788.                     stcl_d(numberstring, faxirides);
  5789.                     strcat(line[RIGHTSIDE][whichline], numberstring);
  5790.                     strcat(line[RIGHTSIDE][whichline], " ");
  5791.                     strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_RIDES2, "rides"));
  5792.                     strcat(line[RIGHTSIDE][whichline], ")");
  5793.                 }
  5794.                 whichline++;
  5795.         }   }
  5796.         if (whichline == oldwhichline)
  5797.         {   strcpy(line[RIGHTSIDE][whichline], " ");
  5798.             strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
  5799.             whichline++;
  5800.         }
  5801.  
  5802.         rightlines = whichline;
  5803.     } elif (countertype == MONSTER)
  5804.     {   strcpy(line[LEFTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_MONSTER_NAME, "Monster Name"));
  5805.         strcat(line[LEFTSIDE][0], ":");
  5806.         pad(line[LEFTSIDE][0]);
  5807.         strcat(line[LEFTSIDE][0], monster[whichcounter].name);
  5808.  
  5809.         strcpy(line[LEFTSIDE][1], GetCatalogStr(li.li_Catalog, MSG_MONSTER_SPECIES, "Monster Species"));
  5810.         strcat(line[LEFTSIDE][1], ":");
  5811.         pad(line[LEFTSIDE][1]);
  5812.         strcat(line[LEFTSIDE][1], monstertypes[monster[whichcounter].species]);
  5813.  
  5814.         strcpy(line[LEFTSIDE][2], GetCatalogStr(li.li_Catalog, MSG_COMBAT_STRENGTH, "Combat Strength"));
  5815.         strcat(line[LEFTSIDE][2], ":");
  5816.         pad(line[LEFTSIDE][2]);
  5817.         stcl_d(numberstring, monster[whichcounter].strength);
  5818.         strcat(line[LEFTSIDE][2], numberstring);
  5819.         
  5820.         strcpy(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_MOVEMENT_FACTOR, "Movement Factor"));
  5821.         strcat(line[LEFTSIDE][3], ":");
  5822.         pad(line[LEFTSIDE][3]);
  5823.         stcl_d(numberstring, monster[whichcounter].moves);
  5824.         strcat(line[LEFTSIDE][3], numberstring);
  5825.         
  5826.         strcpy(line[LEFTSIDE][4], GetCatalogStr(li.li_Catalog, MSG_WEALTH, "Wealth"));
  5827.         strcat(line[LEFTSIDE][4], ":");
  5828.         pad(line[LEFTSIDE][4]);
  5829.         stcl_d(numberstring, monster[whichcounter].wealth);
  5830.         strcat(line[LEFTSIDE][4], numberstring);
  5831.  
  5832.         print_location(monster[whichcounter].where, 5);
  5833.  
  5834.         print_hagall(monster[whichcounter].hagall, 6);
  5835.  
  5836.         print_sea(monster[whichcounter].sea, 7);
  5837.  
  5838.         strcpy(line[LEFTSIDE][8], GetCatalogStr(li.li_Catalog, MSG_TREASURE, "Treasure"));
  5839.         strcat(line[LEFTSIDE][8], "?");
  5840.         pad(line[LEFTSIDE][8]);
  5841.         ok = FALSE;
  5842.         for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  5843.         {   if
  5844.             (   treasure[whichtreasure].possessortype == MONSTER
  5845.              && treasure[whichtreasure].possessor == whichcounter
  5846.             )
  5847.             {   ok = TRUE;
  5848.                 break;
  5849.         }   }
  5850.         if (ok)
  5851.         {   strcat(line[LEFTSIDE][8], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
  5852.         } else
  5853.         {   strcat(line[LEFTSIDE][8], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
  5854.         }
  5855.  
  5856.         leftlines = 9; // counting from 1
  5857.         rightlines = 0;
  5858.     } elif (countertype == JARL)
  5859.     {   strcpy(line[LEFTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_JARL_NAME, "Jarl Name"));
  5860.         strcat(line[LEFTSIDE][0], ":");
  5861.         pad(line[LEFTSIDE][0]);
  5862.         if (jarl[whichcounter].face == FACEUP)
  5863.         {   strcat(line[LEFTSIDE][0], jarl[whichcounter].name);
  5864.         } else
  5865.         {   strcat(line[LEFTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_UNKNOWN, "Unknown"));
  5866.         }
  5867.  
  5868.         strcpy(line[LEFTSIDE][1], GetCatalogStr(li.li_Catalog, MSG_HERO, "Hero"));
  5869.         strcat(line[LEFTSIDE][1], ":");
  5870.         pad(line[LEFTSIDE][1]);
  5871.         if (jarl[whichcounter].hero == -1)
  5872.         {   strcat(line[LEFTSIDE][1], GetCatalogStr(li.li_Catalog, MSG_KING_NONE, "None"));
  5873.         } else
  5874.         {   strcat(line[LEFTSIDE][1], hero[jarl[whichcounter].hero].name);
  5875.         }
  5876.  
  5877.         strcpy(line[LEFTSIDE][2], GetCatalogStr(li.li_Catalog, MSG_COMBAT_STRENGTH, "Combat Strength"));
  5878.         strcat(line[LEFTSIDE][2], ":");
  5879.         pad(line[LEFTSIDE][2]);
  5880.         if (jarl[whichcounter].face == FACEUP)
  5881.         {   stcl_d(numberstring, jarl[whichcounter].strength);
  5882.             strcat(line[LEFTSIDE][2], numberstring);
  5883.         } else
  5884.         {   // assert(jarl[whichcounter].face == FACEDOWN);
  5885.             strcat(line[LEFTSIDE][2], GetCatalogStr(li.li_Catalog, MSG_UNKNOWN, "Unknown"));
  5886.         }
  5887.  
  5888.         strcpy(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_MOVEMENT_FACTOR, "Movement Factor"));
  5889.         strcat(line[LEFTSIDE][3], ":");
  5890.         pad(line[LEFTSIDE][3]);
  5891.         if (jarl[whichcounter].face == FACEUP)
  5892.         {   stcl_d(numberstring, jarl[whichcounter].moves);
  5893.             strcat(line[LEFTSIDE][3], numberstring);
  5894.         } else
  5895.         {   // assert(jarl[whichcounter].face == FACEDOWN);
  5896.             strcat(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_UNKNOWN, "Unknown"));
  5897.         }
  5898.  
  5899.         strcpy(line[LEFTSIDE][4], GetCatalogStr(li.li_Catalog, MSG_WEALTH, "Wealth"));
  5900.         strcat(line[LEFTSIDE][4], ":");
  5901.         pad(line[LEFTSIDE][4]);
  5902.         stcl_d(numberstring, jarl[whichcounter].wealth);
  5903.         strcat(line[LEFTSIDE][4], numberstring);
  5904.  
  5905.         print_location(jarl[whichcounter].where, 5);
  5906.  
  5907.         strcpy(line[LEFTSIDE][6], GetCatalogStr(li.li_Catalog, MSG_HOMELAND, "Homeland"));
  5908.         strcat(line[LEFTSIDE][6], ":");
  5909.         pad(line[LEFTSIDE][6]);
  5910.         strcat(line[LEFTSIDE][6], world[jarl[whichcounter].homewhere].name);
  5911.         strcat(line[LEFTSIDE][6], " (");
  5912.         stcl_d(numberstring, world[jarl[whichcounter].homewhere].tax);
  5913.         strcat(line[LEFTSIDE][6], numberstring);
  5914.         strcat(line[LEFTSIDE][6], ")");
  5915.         
  5916.         strcpy(line[LEFTSIDE][7], GetCatalogStr(li.li_Catalog, MSG_SWORD, "Sword"));
  5917.         strcat(line[LEFTSIDE][7], ":");
  5918.         pad(line[LEFTSIDE][7]);
  5919.         ok = FALSE;
  5920.         for (whichsord = 0; whichsord <= SORDS; whichsord++)
  5921.         {   if
  5922.             (   sord[whichsord].possessortype == JARL
  5923.              && sord[whichsord].possessor == whichcounter
  5924.             )
  5925.             {   ok = TRUE;
  5926.                 counterrow = TRUE;
  5927.                 strcat(line[LEFTSIDE][7], sord[whichsord].name);
  5928.                 break; // for speed
  5929.         }   }
  5930.         if (!ok)
  5931.         {   strcat(line[LEFTSIDE][7], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
  5932.         }
  5933.  
  5934.         print_paralyzed(jarl[whichcounter].loseturn, 8);
  5935.  
  5936.         print_hagall(jarl[whichcounter].hagall, 9);
  5937.  
  5938.         print_sea(jarl[whichcounter].sea, 10);
  5939.  
  5940.         print_routed(jarl[whichcounter].routed, 11);
  5941.  
  5942.         leftlines = 12; // counting from 1
  5943.  
  5944.         strcpy(line[RIGHTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_MAGIC_TREASURES, "Magic Treasures"));
  5945.         strcat(line[RIGHTSIDE][0], ":");
  5946.         whichline = oldwhichline = 1; // whichline always points to the NEXT line.
  5947.         for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  5948.         {   if (treasure[whichtreasure].possessortype == JARL
  5949.              && treasure[whichtreasure].possessor     == whichcounter
  5950.             )
  5951.             {   counterrow = TRUE;
  5952.                 strcpy(line[RIGHTSIDE][whichline], " ");
  5953.                 strcat(line[RIGHTSIDE][whichline], treasure[whichtreasure].name);
  5954.                 if (whichtreasure == FREYFAXI)
  5955.                 {   strcat(line[RIGHTSIDE][whichline], " (");
  5956.                     stcl_d(numberstring, faxirides);
  5957.                     strcat(line[RIGHTSIDE][whichline], numberstring);
  5958.                     strcat(line[RIGHTSIDE][whichline], " ");
  5959.                     strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_RIDES2, "rides"));
  5960.                     strcat(line[RIGHTSIDE][whichline], ")");
  5961.                 }
  5962.                 whichline++;
  5963.         }   }
  5964.         if (whichline == oldwhichline)
  5965.         {   strcpy(line[RIGHTSIDE][whichline], " ");
  5966.             strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
  5967.             whichline++;
  5968.         }
  5969.  
  5970.         rightlines = whichline;
  5971.     } elif (countertype == TREASURE)
  5972.     {   strcpy(line[LEFTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_TREASURE_NAME, "Treasure Name"));
  5973.         strcat(line[LEFTSIDE][0], ":");
  5974.         pad(line[LEFTSIDE][0]);
  5975.         strcat(line[LEFTSIDE][0], treasure[whichcounter].name);
  5976.  
  5977.         print_location(treasure[whichcounter].where, 1);
  5978.  
  5979.         strcpy(line[LEFTSIDE][2], GetCatalogStr(li.li_Catalog, MSG_RIDES, "Rides"));
  5980.         strcat(line[LEFTSIDE][2], ":");
  5981.         if (whichcounter == FREYFAXI)
  5982.         {   // assert(faxirides != -1);
  5983.             stcl_d(numberstring, faxirides);
  5984.             strcat(line[LEFTSIDE][2], numberstring);
  5985.         } else
  5986.         {   strcat(line[LEFTSIDE][2], GetCatalogStr(li.li_Catalog, MSG_N_A, "n/a"));
  5987.         }
  5988.  
  5989.         leftlines = 3;
  5990.         rightlines = 0;
  5991.     } elif (countertype == KINGDOM)
  5992.     {   strcpy(line[LEFTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_KINGDOM_NAME, "Kingdom Name"));
  5993.         strcat(line[LEFTSIDE][0], ":");
  5994.         pad(line[LEFTSIDE][0]);
  5995.         strcat(line[LEFTSIDE][0], world[whichcounter].name);
  5996.  
  5997.         strcpy(line[LEFTSIDE][1], GetCatalogStr(li.li_Catalog, MSG_KING, "King"));
  5998.         strcat(line[LEFTSIDE][1], ":");
  5999.         pad(line[LEFTSIDE][1]);
  6000.         if (world[whichcounter].hero == -1)
  6001.         {   strcat(line[LEFTSIDE][1], GetCatalogStr(li.li_Catalog, MSG_KING_NONE, "None"));
  6002.         } else
  6003.         {   strcat(line[LEFTSIDE][1], hero[world[whichcounter].hero].name);
  6004.         }
  6005.  
  6006.         strcpy(line[LEFTSIDE][2], GetCatalogStr(li.li_Catalog, MSG_TAXATION_FACTOR, "Taxation Factor"));
  6007.         strcat(line[LEFTSIDE][2], ":");
  6008.         pad(line[LEFTSIDE][2]);
  6009.         stcl_d(numberstring, world[whichcounter].tax);
  6010.         strcat(line[LEFTSIDE][2], numberstring);
  6011.  
  6012.         strcpy(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_TYPE, "Type"));
  6013.         strcat(line[LEFTSIDE][3], ":");
  6014.         pad(line[LEFTSIDE][3]);
  6015.         if (world[whichcounter].type == LAND)
  6016.         {   strcat(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_LAND, "Land"));
  6017.         } elif (world[whichcounter].type == ISLE)
  6018.         {   strcat(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_ISLAND, "Island"));
  6019.         } elif (world[whichcounter].type == SEA)
  6020.         {   strcat(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_SEA, "Sea"));
  6021.         } else
  6022.         {   // assert(world[whichcounter].type == PENINSULA);
  6023.             strcat(line[LEFTSIDE][3], GetCatalogStr(li.li_Catalog, MSG_PENINSULA, "Peninsula"));
  6024.         }
  6025.  
  6026.         strcpy(line[LEFTSIDE][4], "Is (");
  6027.         strcat(line[LEFTSIDE][4], GetCatalogStr(li.li_Catalog, MSG_ICE, "ice"));
  6028.         strcat(line[LEFTSIDE][4], ")?");
  6029.         pad(line[LEFTSIDE][4]);
  6030.         if (world[whichcounter].is)
  6031.         {   strcat(line[LEFTSIDE][4], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
  6032.         } else
  6033.         {   strcat(line[LEFTSIDE][4], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
  6034.         }
  6035.                                    
  6036.         leftlines = 5; // counting from 1
  6037.  
  6038.         strcpy(line[RIGHTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_CONTENTS, "Contents"));
  6039.         strcat(line[RIGHTSIDE][0], ":");
  6040.  
  6041.         whichline = oldwhichline = 1; // whichline always points to the NEXT line.
  6042.         for (whichhero = 0; whichhero <= HEROES; whichhero++)
  6043.         {   if (hero[whichhero].alive && hero[whichhero].where == whichcounter)
  6044.             {   strcpy(line[RIGHTSIDE][whichline], " ");
  6045.                 strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_HERO, "Hero"));
  6046.                 strcat(line[RIGHTSIDE][whichline], " ");
  6047.                 strcat(line[RIGHTSIDE][whichline], hero[whichhero].name);
  6048.                 strcat(line[RIGHTSIDE][whichline], " (");
  6049.                 stcl_d(numberstring, hero[whichhero].strength);
  6050.                 strcat(line[RIGHTSIDE][whichline], numberstring);
  6051.                 strcat(line[RIGHTSIDE][whichline], "-");
  6052.                 stcl_d(numberstring, hero[whichhero].moves);
  6053.                 strcat(line[RIGHTSIDE][whichline], numberstring);
  6054.                 strcat(line[RIGHTSIDE][whichline], ")");
  6055.                 whichline++;
  6056.         }   }
  6057.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  6058.         {   if (jarl[whichjarl].alive && jarl[whichjarl].where == whichcounter)
  6059.             {   strcpy(line[RIGHTSIDE][whichline], " ");
  6060.                 if (jarl[whichjarl].face == FACEUP)
  6061.                 {   strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_JARL, "Jarl"));
  6062.                     strcat(line[RIGHTSIDE][whichline], " ");
  6063.                     strcat(line[RIGHTSIDE][whichline], jarl[whichjarl].name);
  6064.                     strcat(line[RIGHTSIDE][whichline], " (");
  6065.                     stcl_d(numberstring, jarl[whichjarl].strength);
  6066.                     strcat(line[RIGHTSIDE][whichline], numberstring);
  6067.                     strcat(line[RIGHTSIDE][whichline], "-");
  6068.                     stcl_d(numberstring, jarl[whichjarl].moves);
  6069.                     strcat(line[RIGHTSIDE][whichline], numberstring);
  6070.                     strcat(line[RIGHTSIDE][whichline], ")");
  6071.                 } else
  6072.                 {   strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_UNKNOWN_JARL, "Unknown jarl"));
  6073.                     strcat(line[RIGHTSIDE][whichline], " (?-?)");
  6074.                 }
  6075.                 whichline++;
  6076.         }   }
  6077.         for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  6078.         {   if (monster[whichmonster].alive && monster[whichmonster].where == whichcounter)
  6079.             {   strcpy(line[RIGHTSIDE][whichline], " ");
  6080.                 strcat(line[RIGHTSIDE][whichline], monstertypes[monster[whichmonster].species]);
  6081.                 strcat(line[RIGHTSIDE][whichline], " ");
  6082.                 strcat(line[RIGHTSIDE][whichline], monster[whichmonster].name);
  6083.                 strcat(line[RIGHTSIDE][whichline], " (");
  6084.                 stcl_d(numberstring, monster[whichmonster].strength);
  6085.                 strcat(line[RIGHTSIDE][whichline], numberstring);
  6086.                 strcat(line[RIGHTSIDE][whichline], "-");
  6087.                 stcl_d(numberstring, monster[whichmonster].moves);
  6088.                 strcat(line[RIGHTSIDE][whichline], numberstring);
  6089.                 strcat(line[RIGHTSIDE][whichline], ")");
  6090.                 whichline++;
  6091.         }   }
  6092.         for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  6093.         {   if
  6094.             (   treasure[whichtreasure].possessortype == KINGDOM
  6095.              && treasure[whichtreasure].where == whichcounter
  6096.             )
  6097.             {   strcpy(line[RIGHTSIDE][whichline], " ");
  6098.                 strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_THE, "The"));
  6099.                 strcat(line[RIGHTSIDE][whichline], " ");
  6100.                 strcat(line[RIGHTSIDE][whichline], treasure[whichtreasure].name);
  6101.                 whichline++;
  6102.         }   }
  6103.         for (whichsord = 0; whichsord <= SORDS; whichsord++)
  6104.         {   if
  6105.             (   sord[whichsord].possessortype == KINGDOM
  6106.              && sord[whichsord].where == whichcounter
  6107.             )
  6108.             {   strcpy(line[RIGHTSIDE][whichline], " ");
  6109.                 strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_SWORD, "Sword"));
  6110.                 strcat(line[RIGHTSIDE][whichline], " ");
  6111.                 strcat(line[RIGHTSIDE][whichline], sord[whichsord].name);
  6112.                 whichline++;
  6113.         }   }
  6114.  
  6115.         if (whichline == oldwhichline)
  6116.         {   strcpy(line[RIGHTSIDE][whichline], " ");
  6117.             strcat(line[RIGHTSIDE][whichline], GetCatalogStr(li.li_Catalog, MSG_NONE, "None"));
  6118.             whichline++;
  6119.         }
  6120.  
  6121.         rightlines = whichline;
  6122.     } elif (countertype == SORD)
  6123.     {   strcpy(line[LEFTSIDE][0], GetCatalogStr(li.li_Catalog, MSG_SWORD_NAME, "Sword Name"));
  6124.         strcat(line[LEFTSIDE][0], ":");
  6125.         pad(line[LEFTSIDE][0]);
  6126.         strcat(line[LEFTSIDE][0], sord[whichcounter].name);
  6127.  
  6128.         print_location(sord[whichcounter].where, 1);
  6129.  
  6130.         leftlines = 2; // counting from 1
  6131.         rightlines = 0;
  6132.     }
  6133.  
  6134.     if (leftlines >= rightlines)
  6135.     {   lines = leftlines;
  6136.     } else
  6137.     {   lines = rightlines;
  6138.     }
  6139.     if (rightlines > 0)
  6140.     {   wide = 1;
  6141.     } else
  6142.     {   wide = 0;
  6143.     }
  6144.  
  6145.     if (!(InfoWindowPtr = (struct Window *) OpenWindowTags(NULL,
  6146.         WA_Left,          (SCREENXPIXEL / 2) - ((360 + (280 * wide )) / 2),
  6147.         WA_Top,           (SCREENYPIXEL / 2) - ( (30 + ( 10 * lines)) / 2),
  6148.         WA_Width,         360 + (280 * wide ),
  6149.         WA_Height,         30 + ( 10 * lines),
  6150.         WA_IDCMP,         IDCMP_CLOSEWINDOW | IDCMP_RAWKEY,
  6151.         WA_Title,         GetCatalogStr(li.li_Catalog, MSG_INFORMATION, "Information"),
  6152.         WA_Gadgets,       NULL,
  6153.         WA_CustomScreen,  ScreenPtr,
  6154.         WA_DragBar,       TRUE,
  6155.         WA_CloseGadget,   TRUE,
  6156.         WA_NoCareRefresh, TRUE,
  6157.         WA_Activate,      TRUE,
  6158.     TAG_DONE))
  6159.     )
  6160.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open information window!\0", 24);
  6161.         cleanexit(EXIT_FAILURE);
  6162.     }
  6163.     /* if (countertype == HERO)
  6164.     {   SetAPen(InfoWindowPtr->RPort, herocolour[whichcounter]);
  6165.     } elif (countertype == JARL && jarl[counter].hero != -1)
  6166.     {   SetAPen(InfoWindowPtr->RPort, herocolour[jarl[whichcounter].hero]);
  6167.     } elif (countertype == KINGDOM && world[counter].hero != -1)
  6168.     {   SetAPen(InfoWindowPtr->RPort, herocolour[world[whichcounter].hero]);
  6169.     } if we had a free pen, we could do this... else
  6170.     {   */ SetAPen(InfoWindowPtr->RPort, LIGHTGREY);
  6171.  /* } */
  6172.     RectFill(InfoWindowPtr->RPort, 8, 13, 360 + (280 * wide) - 10, 30 + (10 * lines) - 6);
  6173.     SetAPen(InfoWindowPtr->RPort, BLACK);
  6174.     SetDrMd(InfoWindowPtr->RPort, JAM1);
  6175.  
  6176.     for (whichline = 0; whichline < leftlines; whichline++)
  6177.     {   Move(InfoWindowPtr->RPort, 16, 26 + (whichline * 10));
  6178.         Text(InfoWindowPtr->RPort, line[LEFTSIDE][whichline], strlen(line[LEFTSIDE][whichline]));
  6179.     }
  6180.     if (wide)
  6181.     {   for (whichline = 0; whichline < rightlines; whichline++)
  6182.         {   Move(InfoWindowPtr->RPort, 320 + 16, 26 + (whichline * 10));
  6183.             Text(InfoWindowPtr->RPort, line[RIGHTSIDE][whichline], strlen(line[RIGHTSIDE][whichline]));
  6184.     }   }
  6185.  
  6186.     if (counterrow)
  6187.     {   if (countertype == HERO)
  6188.         {   hero_info(whichcounter);
  6189.         } else
  6190.         {   assert(countertype == JARL);
  6191.             jarl_info(whichcounter);
  6192.     }   }
  6193.  
  6194.     while(!done)
  6195.     {   Wait(1L << InfoWindowPtr->UserPort->mp_SigBit);
  6196.         while (MsgPtr = (struct IntuiMessage *) GetMsg(InfoWindowPtr->UserPort))
  6197.         {   class  = MsgPtr->Class;
  6198.             code   = MsgPtr->Code;
  6199.             qual   = MsgPtr->Qualifier;
  6200.             ReplyMsg((struct Message *) MsgPtr);
  6201.             switch(class)
  6202.             {
  6203.             case IDCMP_CLOSEWINDOW:
  6204.                 done = TRUE;
  6205.             break;
  6206.             case IDCMP_RAWKEY:
  6207.                 if (!(qual & IEQUALIFIER_REPEAT) && code < KEYUP && (code < FIRSTQUALIFIER || code > LASTQUALIFIER))
  6208.                 {   done = TRUE;
  6209.                 }
  6210.             break;
  6211.             default:
  6212.             break;
  6213.     }   }   }
  6214.  
  6215.     if (counterrow)
  6216.     {   uninfo();
  6217.     }
  6218.     CloseWindow(InfoWindowPtr);
  6219.     InfoWindowPtr = NULL;
  6220.     clearkybd();
  6221. }
  6222.  
  6223. MODULE void getdefender(SLONG attackhero, SLONG here)
  6224. {   FLAG  done = FALSE;
  6225.     SLONG counter, countertype, defendtype, defender, whichattack,
  6226.           whichjarl;
  6227.  
  6228.     do
  6229.     {   saywho(HERO, attackhero, TRUE, FALSE);
  6230.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_SELECT_DEFENDER, "select defender"));
  6231.         strcat(saystring, "?");
  6232.         say(LOWER);
  6233.  
  6234.         counter = getevent(COUNTER, &countertype);
  6235.         if (counter == -2 || counter == -3)
  6236.         {   // user wants to quit (back to `select attacker')
  6237.             if (hero[attackhero].attacking)
  6238.             {   deselect_hero(attackhero, TRUE);
  6239.             }
  6240.             for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  6241.             {   if (jarl[whichjarl].alive && jarl[whichjarl].attacking)
  6242.                 {   deselect_jarl(whichjarl, TRUE);
  6243.             }   }
  6244.             return;
  6245.         } elif (countertype == HERO) // if an enemy hero
  6246.         {   if (counter != attackhero && hero[counter].where == here)
  6247.             {   defendtype = HERO;
  6248.                 defender = counter;
  6249.                 done = TRUE;
  6250.         }   }
  6251.         elif (countertype == JARL) // if an enemy jarl
  6252.         {   if (jarl[counter].hero != attackhero && jarl[counter].where == here)
  6253.             {   defendtype = JARL;
  6254.                 defender = counter;
  6255.                 done = TRUE;
  6256.         }   }
  6257.         elif (countertype == MONSTER) // if a monster
  6258.         {   if (monster[counter].where == here)
  6259.             {   defendtype = MONSTER;
  6260.                 defender = counter;
  6261.                 done = TRUE;
  6262.         }   }
  6263.         elif (countertype == KINGDOM)
  6264.         {   if
  6265.             (    world[counter].hero != attackhero
  6266.               && counter <= 35
  6267.               && counter == here
  6268.             )
  6269.             {   defendtype = KINGDOM;
  6270.                 defender = counter;
  6271.                 done = TRUE;
  6272.         }   }
  6273.  
  6274.         if (done)
  6275.         {   if (hero[attackhero].attacking)
  6276.             {   // check if the hero has already fought this
  6277.                 for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  6278.                 {   if
  6279.                     (   hero[attackhero].attacktype[whichattack] == countertype
  6280.                      && hero[attackhero].attacked[whichattack]   == counter
  6281.                     )
  6282.                     {   done = FALSE;
  6283.  
  6284.                         saywho(HERO, attackhero, FALSE, FALSE);
  6285.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_H_A_F_T_T_T, "has already fought that this turn"));
  6286.                         strcat(saystring, ".");
  6287.                         say(LOWER);
  6288.                         anykey();
  6289.                         break; // for speed
  6290.             }   }   }
  6291.             for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  6292.             {   if (jarl[whichjarl].attacking)
  6293.                 {   for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  6294.                     {   if
  6295.                         (   jarl[whichjarl].attacktype[whichattack] == countertype
  6296.                          && jarl[whichjarl].attacked[whichattack]   == counter
  6297.                         )
  6298.                         {   done = FALSE;
  6299.  
  6300.                             saywho(JARL, whichjarl, FALSE, FALSE);
  6301.                             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_H_A_F_T_T_T, "has already fought that this turn"));
  6302.                             strcat(saystring, ".");
  6303.                             say(LOWER);
  6304.                             anykey();
  6305.                             break; // for speed
  6306.         }   }   }   }   }
  6307.         else
  6308.         {   ; // DisplayBeep(ScreenPtr);
  6309.     }   }
  6310.     while (!done);
  6311.  
  6312.     // ok, going ahead with the battle
  6313.     if (countertype == JARL && jarl[counter].face == FACEDOWN)
  6314.     {   revealjarl(counter, TRUE);
  6315.     }
  6316.     if (hero[attackhero].attacking)
  6317.     {   for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  6318.         {   if (hero[attackhero].attacktype[whichattack] == -1)
  6319.             {   hero[attackhero].attacktype[whichattack] = countertype;
  6320.                 hero[attackhero].attacked[whichattack]   = counter;
  6321.                 break;
  6322.     }   }   }
  6323.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  6324.     {   if (jarl[whichjarl].attacking)
  6325.         {   for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  6326.             {   if (jarl[whichjarl].attacktype[whichattack] == -1)
  6327.                 {   jarl[whichjarl].attacktype[whichattack] = countertype;
  6328.                     jarl[whichjarl].attacked[whichattack]   = counter;
  6329.                     break;
  6330.     }   }   }   }
  6331.  
  6332.     dobattle(countertype, counter, attackhero);
  6333. }
  6334.  
  6335. MODULE FLAG needsord(SLONG countertype, SLONG counter)
  6336. {   SLONG whichsord;
  6337.  
  6338.     for (whichsord = 0; whichsord <= SORDS; whichsord++)
  6339.     {   if
  6340.         (   sord[whichsord].possessortype == countertype
  6341.          && sord[whichsord].possessor == counter
  6342.         )
  6343.         {   return(FALSE);
  6344.     }   }
  6345.     return(TRUE);
  6346. }
  6347.  
  6348. MODULE void brosung(SLONG countertype, SLONG whichcounter)
  6349. {   SLONG result, whichconnection, whichmonster, whichtreasure, where;
  6350.    
  6351.     for (whichconnection = 0; whichconnection <= CONNECTIONS; whichconnection++)
  6352.     {   if (countertype == HERO)
  6353.         {   where = world[hero[whichcounter].where].connection[whichconnection];
  6354.         } else
  6355.         {   assert(countertype == JARL);
  6356.             where = world[jarl[whichcounter].where].connection[whichconnection];
  6357.         }
  6358.         if (where == -1)
  6359.         {   break;
  6360.         }
  6361.         for (whichmonster = 0; whichmonster <= MONSTERS; whichmonster++)
  6362.         {   if
  6363.             (   monster[whichmonster].alive
  6364.              && monster[whichmonster].species == DRAGON
  6365.              && monster[whichmonster].where == where
  6366.             )
  6367.             {   // there is a dragon here
  6368.                 for (whichtreasure = 0; whichtreasure <= TREASURES; whichtreasure++)
  6369.                 {   if
  6370.                     (   treasure[whichtreasure].possessortype == MONSTER
  6371.                      && treasure[whichtreasure].possessor == whichmonster
  6372.                     )
  6373.                     {   /* We know it is human control because we
  6374.                            don't call this function for Amiga heroes/jarls */
  6375.  
  6376.                         saywho(countertype, whichcounter, TRUE, FALSE);
  6377.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_EXCHANGE_THE, "exchange the"));
  6378.                         strcat(saystring, " ");
  6379.                         strcat(saystring, treasure[BROSUNGNECKLACE].name);
  6380.                         strcat(saystring, " ");
  6381.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_WITH, "with"));
  6382.                         strcat(saystring, " ");
  6383.                         strcat(saystring, monstertypes[DRAGON]);
  6384.                         strcat(saystring, " ");
  6385.                         strcat(saystring, monster[whichmonster].name);
  6386.                         strcat(saystring, " (");
  6387.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_YES, "Y"));
  6388.                         strcat(saystring, "/");
  6389.                         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_NO, "N"));
  6390.                         strcat(saystring, ")?");
  6391.                         say(LOWER);
  6392.                         do
  6393.                         {   result = getevent(KEYBOARD, NULL);
  6394.                         } while (result != onekey[ONEKEY_YES] && result != onekey[ONEKEY_NO]);
  6395.                         if (result == onekey[ONEKEY_YES])
  6396.                         {   // give the dragon's treasure to the hero/jarl
  6397.                             treasure[whichtreasure].possessortype   = countertype;
  6398.                             treasure[whichtreasure].possessor       = whichcounter;
  6399.  
  6400.                             saywho(countertype, whichcounter, TRUE, FALSE);
  6401.                             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKES_THE, "takes the"));
  6402.                             strcat(saystring, " ");
  6403.                             strcat(saystring, treasure[whichtreasure].name);
  6404.                             strcat(saystring, ".");
  6405.                             say(LOWER);
  6406.  
  6407.                             // give the hero/jarl's treasure to the dragon
  6408.                             treasure[BROSUNGNECKLACE].possessortype = MONSTER;
  6409.                             treasure[BROSUNGNECKLACE].possessor     = whichmonster;
  6410.                             break;
  6411. }   }   }   }   }   }   }
  6412.  
  6413. MODULE void flash(SLONG country)
  6414. {   SLONG colour;
  6415.  
  6416.     if (country < 0 || country > 65)
  6417.     {   return;
  6418.     }
  6419.  
  6420.     if (country == 9)
  6421.     {   colour = 89; // Suder Gotland
  6422.     } elif (country == 10)
  6423.     {   colour = 90; // Juteland
  6424.     } elif (country == 11)
  6425.     {   colour = 91; // Scandia
  6426.     } else
  6427.     {   colour = country + 8;
  6428.     }
  6429.  
  6430.     SetRGB4(&ScreenPtr->ViewPort, colour, 15, 15, 15); // white flash
  6431.     Delay(2); // hold the flash
  6432.  
  6433.     if (country >= 36)
  6434.     {   SetRGB4(&ScreenPtr->ViewPort, colour,  0,  0,  9); // dark blue
  6435.     } elif (world[country].hero != -1)
  6436.     {   SetRGB4
  6437.         (   &ScreenPtr->ViewPort,
  6438.             colour,
  6439.             herocolour[world[country].hero].red,
  6440.             herocolour[world[country].hero].green,
  6441.             herocolour[world[country].hero].blue
  6442.         );
  6443.     } elif (world[country].is)
  6444.     {   SetRGB4(&ScreenPtr->ViewPort, colour, 12, 12, 12); // light grey ice
  6445.     } else
  6446.     {   SetRGB4
  6447.         (   &ScreenPtr->ViewPort,
  6448.             colour,
  6449.             taxcolours[world[country].tax].red,
  6450.             taxcolours[world[country].tax].green,
  6451.             taxcolours[world[country].tax].blue
  6452.         );
  6453. }   }
  6454.  
  6455. MODULE FLAG assess(SLONG countertype, SLONG counter)
  6456. {   return(FALSE);
  6457. }
  6458.  
  6459. MODULE void promote(SLONG whichhero, SLONG whichjarl)
  6460. {   remove_jarl(whichjarl, TRUE);
  6461.     jarl[whichjarl].alive     = FALSE;
  6462.     hero[whichhero].alive     = TRUE;
  6463.     hero[whichhero].promoted  = whichjarl;
  6464.     hero[whichhero].name      = jarl[whichjarl].name;
  6465.     hero[whichhero].moves     = jarl[whichjarl].moves;
  6466.     hero[whichhero].strength  = jarl[whichjarl].strength;
  6467.     hero[whichhero].where     = jarl[whichjarl].where;
  6468.     hero[whichhero].homewhere = jarl[whichjarl].homewhere;
  6469.     hero[whichhero].god       =
  6470.     hero[whichhero].rune      = -1;
  6471.     hero[whichhero].maidens   =
  6472.     hero[whichhero].glory     = 0;
  6473.     hero[whichhero].hagall    = jarl[whichjarl].hagall;
  6474.     hero[whichhero].loseturn  = jarl[whichjarl].loseturn;
  6475.     hero[whichhero].wealth    = jarl[whichjarl].wealth;
  6476.     hero[whichhero].wounded   = FALSE;
  6477.     deselect_hero(whichhero, TRUE);
  6478.     move_hero(whichhero, TRUE);
  6479. }
  6480.  
  6481. MODULE void withdraw(SLONG whichhero)
  6482. {   SLONG whichcountry, whichjarl;
  6483.  
  6484.     hero[whichhero].verydead = TRUE;
  6485.  
  6486.     // all the jarls of the dead hero are freed
  6487.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  6488.     {   if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
  6489.         {   jarl[whichjarl].hero = -1;
  6490.     }   }
  6491.  
  6492.     // all the kingdoms of the dead hero declare independence
  6493.     for (whichcountry = 0; whichcountry <= 35; whichcountry++)
  6494.     {   if (world[whichcountry].hero == whichhero)
  6495.         {   world[whichcountry].hero = -1;
  6496.     }   }
  6497.  
  6498.     darken();
  6499. }
  6500.  
  6501. MODULE FLAG asksord(SLONG countertype, SLONG counter, SLONG whichsord)
  6502. {   SLONG result, whichcountry;
  6503.  
  6504.     if (countertype == JARL)
  6505.     {   whichcountry = jarl[counter].where;
  6506.     } else
  6507.     {   whichcountry = hero[counter].where;
  6508.     }
  6509.  
  6510.     saywho(countertype, counter, FALSE, FALSE);
  6511.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IN, "in"));
  6512.     strcat(saystring, " ");
  6513.     strcat(saystring, world[whichcountry].name);
  6514.     strcat(saystring, ", ");
  6515.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKE_SWORD, "take sword"));
  6516.     strcat(saystring, " ");
  6517.     strcat(saystring, sord[whichsord].name);
  6518.     strcat(saystring, " (");
  6519.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_YES, "Y"));
  6520.     strcat(saystring, "/");
  6521.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_NO, "N"));
  6522.     strcat(saystring, ")?");
  6523.     say(LOWER);
  6524.     do
  6525.     {   result = getevent(KEYBOARD, NULL);
  6526.     } while (result != onekey[ONEKEY_YES] && result != onekey[ONEKEY_NO]);
  6527.     if (result == onekey[ONEKEY_YES])
  6528.     {   remove_sord(whichsord, TRUE);
  6529.         sord[whichsord].possessortype = countertype;
  6530.         sord[whichsord].possessor     = counter;
  6531.         sord[whichsord].where         = -1;
  6532.         return(TRUE);
  6533.     }
  6534.     // assert(result == onekey[ONEKEY_NO]);
  6535.     return(FALSE);
  6536. }
  6537.  
  6538.  
  6539. MODULE void asktreasure(SLONG countertype, SLONG counter, SLONG whichtreasure)
  6540. {   SLONG result, whichcountry;
  6541.  
  6542.     if (countertype == JARL)
  6543.     {   whichcountry = jarl[counter].where;
  6544.     } else
  6545.     {   whichcountry = hero[counter].where;
  6546.     }
  6547.  
  6548.     saywho(countertype, counter, FALSE, FALSE);
  6549.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_IN, "in"));
  6550.     strcat(saystring, " ");
  6551.     strcat(saystring, world[whichcountry].name);
  6552.     strcat(saystring, ", ");
  6553.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_TAKE_THE, "take the"));
  6554.     strcat(saystring, " ");
  6555.     strcat(saystring, treasure[whichtreasure].name);
  6556.     strcat(saystring, " (");
  6557.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_YES, "Y"));
  6558.     strcat(saystring, "/");
  6559.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_NO, "N"));
  6560.     strcat(saystring, ")?");
  6561.     say(LOWER);
  6562.     do
  6563.     {   result = getevent(KEYBOARD, NULL);
  6564.     } while (result != onekey[ONEKEY_YES] && result != onekey[ONEKEY_NO]);
  6565.     if (result == onekey[ONEKEY_YES])
  6566.     {   remove_treasure(whichtreasure, TRUE);
  6567.         treasure[whichtreasure].possessortype = countertype;
  6568.         treasure[whichtreasure].possessor     = counter;
  6569.         treasure[whichtreasure].where         = -1;
  6570. }   }
  6571.  
  6572. MODULE void pad(STRPTR thestring)
  6573. {   SLONG i, length;
  6574.  
  6575.     length = strlen(thestring);
  6576.  
  6577.     if (length < 21)
  6578.     {   for (i = length; i <= 21; i++)
  6579.         {   strcat(thestring, " ");
  6580. }   }   }
  6581.  
  6582. MODULE void print_location(SLONG whichcountry, SLONG index)
  6583. {   strcpy(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_LOCATION, "Location"));
  6584.     strcat(line[LEFTSIDE][index], ":");
  6585.     pad(line[LEFTSIDE][index]);
  6586.     strcat(line[LEFTSIDE][index], world[whichcountry].name);
  6587.     strcat(line[LEFTSIDE][index], " (");
  6588.     stcl_d(numberstring, world[whichcountry].tax);
  6589.     strcat(line[LEFTSIDE][index], numberstring);
  6590.     strcat(line[LEFTSIDE][index], ")");
  6591. }
  6592.  
  6593. MODULE void print_sea(SLONG sea_value, SLONG index)
  6594. {   strcpy(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_MOVE_BY_SEA, "Move by sea"));
  6595.     strcat(line[LEFTSIDE][index], "?");
  6596.     pad(line[LEFTSIDE][index]);
  6597.     if (sea_value == NORMAL)
  6598.     {   strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
  6599.     } elif (sea_value == BAD)
  6600.     {   strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
  6601.     } else
  6602.     {   // assert(sea_value == GOOD);
  6603.         strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_SPECIAL, "Special"));
  6604. }   }
  6605.  
  6606. MODULE void print_hagall(SLONG hagall_value, SLONG index)
  6607. {   strcpy(line[LEFTSIDE][index], "Hagall (");
  6608.     strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_SLOWED, "slowed"));
  6609.     strcat(line[LEFTSIDE][index], ")?");
  6610.     pad(line[LEFTSIDE][index]);
  6611.     if (hagall_value)
  6612.     {   strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
  6613.     } else
  6614.     {   strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
  6615. }   }
  6616.  
  6617. MODULE void print_paralyzed(SLONG loseturn_value, SLONG index)
  6618. {   strcpy(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_PARALYZED, "Paralyzed"));
  6619.     strcat(line[LEFTSIDE][index], "?");
  6620.     pad(line[LEFTSIDE][index]);
  6621.     if (loseturn_value)
  6622.     {   strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
  6623.     } else
  6624.     {   strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
  6625. }   }
  6626.  
  6627. MODULE void print_routed(SLONG routed_value, SLONG index)
  6628. {   strcpy(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_ROUTED, "Routed"));
  6629.  
  6630.     strcat(line[LEFTSIDE][index], "?");
  6631.     pad(line[LEFTSIDE][index]);
  6632.     if (routed_value)
  6633.     {   strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_YES, "Yes"));
  6634.     } else
  6635.     {   strcat(line[LEFTSIDE][index], GetCatalogStr(li.li_Catalog, MSG_NO, "No"));
  6636. }   }
  6637.  
  6638. MODULE void amiga_attack(SLONG attackhero, SLONG defendtype, SLONG defender)
  6639. {   SLONG whichattack, whichjarl;
  6640.  
  6641.     // ok, going ahead with the battle
  6642.     if (defendtype == JARL && jarl[defender].face == FACEDOWN)
  6643.     {   revealjarl(defender, TRUE);
  6644.     }
  6645.     if (hero[attackhero].attacking)
  6646.     {   for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  6647.         {   if (hero[attackhero].attacktype[whichattack] == -1)
  6648.             {   hero[attackhero].attacktype[whichattack] = defendtype;
  6649.                 hero[attackhero].attacked[whichattack]   = defender;
  6650.                 break;
  6651.     }   }   }
  6652.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  6653.     {   if (jarl[whichjarl].attacking)
  6654.         {   for (whichattack = 0; whichattack <= ATTACKS; whichattack++)
  6655.             {   if (jarl[whichjarl].attacktype[whichattack] == -1)
  6656.                 {   jarl[whichjarl].attacktype[whichattack] = defendtype;
  6657.                     jarl[whichjarl].attacked[whichattack]   = defender;
  6658.                     break;
  6659.     }   }   }   }
  6660.  
  6661.     saywho(HERO, attackhero, FALSE, FALSE);
  6662.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_ATTACKS, "attacks"));
  6663.  
  6664.     if (defendtype == HERO || defendtype == JARL)
  6665.     {   saywho(defendtype, defender, FALSE, TRUE);
  6666.     } elif (defendtype == MONSTER)
  6667.     {   strcat(saystring, " ");
  6668.         strcat(saystring, monstertypes[monster[defender].species]);
  6669.         strcat(saystring, " ");
  6670.         strcat(saystring, monster[defender].name);
  6671.     } else
  6672.     {   // assert(defendtype == KINGDOM);
  6673.         strcat(saystring, " ");
  6674.         if (world[defender].hero != -1)
  6675.         {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO2, "hero"));
  6676.             strcat(saystring, " ");
  6677.             strcat(saystring, hero[world[defender].hero].name);
  6678.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S, "'s"));
  6679.             strcat(saystring, " ");
  6680.         }
  6681.         strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_KINGDOM, "kingdom"));
  6682.         strcat(saystring, " ");
  6683.         strcat(saystring, world[defender].name);
  6684.         strcat(saystring, " (");
  6685.         stcl_d(numberstring, world[defender].tax);
  6686.         strcat(saystring, numberstring);
  6687.         strcat(saystring, ")");
  6688.     }
  6689.  
  6690.     strcat(saystring, ".");
  6691.     say(LOWER);
  6692.     anykey();
  6693.     dobattle(defendtype, defender, attackhero);
  6694. }
  6695.  
  6696. MODULE FLAG ask_faxi(SLONG countertype, SLONG whichcounter)
  6697. {   SLONG result;
  6698.  
  6699.     saywho(countertype, whichcounter, TRUE, FALSE);
  6700.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_RIDE_THE, "ride the"));
  6701.     strcat(saystring, " ");
  6702.     strcat(saystring, treasure[FREYFAXI].name);
  6703.     strcat(saystring, " (");
  6704.     stcl_d(numberstring, faxirides);
  6705.     strcat(saystring, numberstring);
  6706.     strcat(saystring, " ");
  6707.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_RIDES2, "rides"));
  6708.     strcat(saystring, ") (");
  6709.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_YES, "Y"));
  6710.     strcat(saystring, "/");
  6711.     strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_CHAR_NO, "N"));
  6712.     strcat(saystring, ")?");
  6713.     say(LOWER);
  6714.  
  6715.     do
  6716.     {    result = getevent(KEYBOARD, NULL);
  6717.     } while (result != onekey[ONEKEY_YES] && result != onekey[ONEKEY_NO]);
  6718.     if (result == onekey[ONEKEY_YES])
  6719.     {   faxirides--;
  6720.         faxi_disappear();
  6721.         return(TRUE);
  6722.     }
  6723.     return(FALSE);
  6724. }
  6725.  
  6726. MODULE void saywho(SLONG countertype, SLONG counter, FLAG comma, FLAG lowercase)
  6727. {   if (!lowercase)
  6728.     {   saystring[0] = 0;
  6729.     } else
  6730.     {   strcat(saystring, " ");
  6731.     }
  6732.     if (countertype == HERO)
  6733.     {   if (!lowercase)
  6734.         {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO, "Hero"));
  6735.         } else
  6736.         {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO2, "hero"));
  6737.         }
  6738.         strcat(saystring, " ");
  6739.         strcat(saystring, hero[counter].name);
  6740.     } else
  6741.     {   // assert(countertype == JARL);
  6742.         if (jarl[counter].hero != -1)
  6743.         {   if (!lowercase)
  6744.             {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO, "Hero"));
  6745.             } else
  6746.             {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_HERO2, "hero"));
  6747.             }
  6748.             strcat(saystring, " ");
  6749.             strcat(saystring, hero[jarl[counter].hero].name);
  6750.             strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_S_JARL, "'s jarl"));
  6751.         } else
  6752.         {   if (!lowercase)
  6753.             {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_JARL, "Jarl"));
  6754.             } else
  6755.             {   strcat(saystring, GetCatalogStr(li.li_Catalog, MSG_JARL2, "jarl"));
  6756.         }   }
  6757.         strcat(saystring, " ");
  6758.         strcat(saystring, jarl[counter].name);
  6759.     }
  6760.     if (!lowercase)
  6761.     {   if (comma)
  6762.         {   strcat(saystring, ",");
  6763.         }
  6764.         strcat(saystring, " ");
  6765. }   }
  6766.  
  6767. MODULE FLAG attackersleft(void)
  6768. {   SLONG whichhero, whichjarl;
  6769.  
  6770.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  6771.     {   if (hero[whichhero].attacking)
  6772.         {   return(TRUE);
  6773.     }   }
  6774.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  6775.     {   if (jarl[whichjarl].attacking)
  6776.         {   return(TRUE);
  6777.     }   }
  6778.     return(FALSE);
  6779. }
  6780.  
  6781. MODULE void summarywindow(void)
  6782. {   SLONG                i,
  6783.                          jarls,
  6784.                          kingdoms,
  6785.                          length,
  6786.                          treasures,
  6787.                          wealth,
  6788.                          whichcountry,
  6789.                          whichjarl,
  6790.                          whichhero,
  6791.                          whichtreasure,
  6792.                          whichsord;
  6793.     FLAG                 done = FALSE,
  6794.                          ok;
  6795.     ULONG                class;
  6796.     UWORD                code, qual;
  6797.     struct IntuiMessage* MsgPtr;
  6798.  
  6799.     strcpy(line[0][0], GetCatalogStr(li.li_Catalog, MSG_SUMMARYLINE, "Hero Name  C-M J K S T C S R Glry Luck $$$$"));
  6800.  
  6801.                      /* Hero Name  C-M J K S T C S R Glry Luck $$$$
  6802.                                    o o a i w r o t u
  6803.                                    m v r n o e n a n
  6804.                                    b e l g r a t t e
  6805.                                    a m s d d s r u s
  6806.                                    t e   o   u o s
  6807.                                      n   m   r l
  6808.                                      t   s   e
  6809.                                              s
  6810.  
  6811.                         Heldenname K-B J K S S K S @ Ruhm Glck $$$$
  6812.                                    a e a ö c c o t @
  6813.                                    m w r n h h n a @
  6814.                                    p e l i w ä t t @
  6815.                                    f g s g e t r u @
  6816.                                      u   r r z o s @
  6817.                                      n   e t e l
  6818.                                      g   i     l
  6819.                                      s   c     e
  6820.                                          h
  6821.                                          e */
  6822.  
  6823.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  6824.     {   strcpy(line[0][whichhero + 1], hero[whichhero].name);
  6825.  
  6826.         length = strlen(hero[whichhero].name);
  6827.         for (i = length; i < 11; i++)
  6828.         {   strcat(line[0][whichhero + 1], " ");
  6829.         }
  6830.  
  6831.         stcl_d(numberstring, hero[whichhero].strength);
  6832.         strcat(line[0][whichhero + 1], numberstring);
  6833.         strcat(line[0][whichhero + 1], "-");
  6834.  
  6835.         stcl_d(numberstring, hero[whichhero].moves);
  6836.         strcat(line[0][whichhero + 1], numberstring);
  6837.         strcat(line[0][whichhero + 1], " ");
  6838.  
  6839.         jarls = 0;
  6840.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  6841.         {   if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
  6842.             {   jarls++;
  6843.         }   }
  6844.         stcl_d(numberstring, jarls);
  6845.         strcat(line[0][whichhero + 1], numberstring);
  6846.         strcat(line[0][whichhero + 1], " ");
  6847.  
  6848.         kingdoms = 0;
  6849.         for (whichcountry = 0; whichcountry <= 35; whichcountry++)
  6850.         {   if (world[whichcountry].hero == whichhero)
  6851.             {   kingdoms++;
  6852.         }   }
  6853.         stcl_d(numberstring, kingdoms);
  6854.         strcat(line[0][whichhero + 1], numberstring);
  6855.         strcat(line[0][whichhero + 1], " ");
  6856.  
  6857.         ok = FALSE;
  6858.         for (whichsord = 0; whichsord <= SORDS; whichsord++)
  6859.         {   if
  6860.             (   sord[whichsord].possessortype == HERO
  6861.              && sord[whichsord].possessor     == whichhero
  6862.             )
  6863.             {   numberstring[0] = sord[whichsord].name[0];
  6864.                 numberstring[1] = 0;
  6865.                 strcat(line[0][whichhero + 1], numberstring);
  6866.                 ok = TRUE;
  6867.                 break;
  6868.         }   }
  6869.         if (!ok)
  6870.         {   strcat(line[0][whichhero + 1], "-");
  6871.         }
  6872.         strcat(line[0][whichhero + 1], " ");
  6873.  
  6874.         treasures = 0;
  6875.         for (whichtreasure = 0; whichtreasure <= SORDS; whichtreasure++)
  6876.         {   if
  6877.             (   (   treasure[whichtreasure].possessortype == HERO
  6878.                  && treasure[whichtreasure].possessor     == whichhero
  6879.                 )
  6880.              || (   treasure[whichtreasure].possessortype == JARL
  6881.                  && jarl[treasure[whichtreasure].possessor].hero == whichhero
  6882.             )   )
  6883.             {   treasures++;
  6884.         }   }
  6885.         stcl_d(numberstring, treasures);
  6886.         strcat(line[0][whichhero + 1], numberstring);
  6887.         strcat(line[0][whichhero + 1], " ");
  6888.  
  6889.         if (hero[whichhero].control == HUMAN)
  6890.         {   strcat(line[0][whichhero + 1], GetCatalogStr(li.li_Catalog, MSG_CHAR_HUMAN, "H"));
  6891.         } elif (hero[whichhero].control == AMIGA)
  6892.         {   strcat(line[0][whichhero + 1], "A");
  6893.         } else
  6894.         {   // assert(hero[whichhero].control == NONE);
  6895.             strcat(line[0][whichhero + 1], "-");
  6896.         }
  6897.         strcat(line[0][whichhero + 1], " ");
  6898.  
  6899.         if (!hero[whichhero].alive)
  6900.         {   strcat(line[0][whichhero + 1], GetCatalogStr(li.li_Catalog, MSG_CHAR_DEAD,    "D"));
  6901.         } elif (hero[whichhero].wounded)
  6902.         {   strcat(line[0][whichhero + 1], GetCatalogStr(li.li_Catalog, MSG_CHAR_WOUNDED, "W"));
  6903.         } else
  6904.         {   strcat(line[0][whichhero + 1], GetCatalogStr(li.li_Catalog, MSG_CHAR_GOOD,    "G"));
  6905.         }
  6906.  
  6907.         strcat(line[0][whichhero + 1], " ");
  6908.         if (hero[whichhero].rune == -1)
  6909.         {   strcat(line[0][whichhero + 1], "-");
  6910.         } else
  6911.         {   numberstring[0] = runename[hero[whichhero].rune][0];
  6912.             numberstring[1] = 0;
  6913.             strcat(line[0][whichhero + 1], numberstring);
  6914.         }
  6915.  
  6916.         stcl_d(numberstring, hero[whichhero].glory);
  6917.         length = strlen(numberstring);
  6918.         for (i = length; i < 5; i++)
  6919.         {   strcat(line[0][whichhero + 1], " ");
  6920.         }
  6921.         strcat(line[0][whichhero + 1], numberstring);
  6922.  
  6923.         stcl_d(numberstring, hero[whichhero].luck);
  6924.         length = strlen(numberstring);
  6925.         for (i = length; i < 5; i++)
  6926.         {   strcat(line[0][whichhero + 1], " ");
  6927.         }
  6928.         strcat(line[0][whichhero + 1], numberstring);
  6929.  
  6930.         wealth = hero[whichhero].wealth;
  6931.         for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  6932.         {   if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero)
  6933.             {   wealth += jarl[whichjarl].wealth;
  6934.         }   }
  6935.         stcl_d(numberstring, wealth);
  6936.         length = strlen(numberstring);
  6937.         for (i = length; i < 5; i++)
  6938.         {   strcat(line[0][whichhero + 1], " ");
  6939.         }
  6940.         strcat(line[0][whichhero + 1], numberstring);
  6941.     }
  6942.  
  6943.     if (!(InfoWindowPtr = (struct Window *) OpenWindowTags(NULL,
  6944.         WA_Left,          (SCREENXPIXEL / 2) - (378 / 2),
  6945.         WA_Top,           (SCREENYPIXEL / 2) - (102 / 2),
  6946.         WA_Width,         378,
  6947.         WA_Height,        102,
  6948.         WA_IDCMP,         IDCMP_CLOSEWINDOW | IDCMP_RAWKEY,
  6949.         WA_Title,         GetCatalogStr(li.li_Catalog, MSG_GAME_SUMMARY, "Game Summary"),
  6950.         WA_Gadgets,       NULL,
  6951.         WA_CustomScreen,  ScreenPtr,
  6952.         WA_DragBar,       TRUE,
  6953.         WA_CloseGadget,   TRUE,
  6954.         WA_NoCareRefresh, TRUE,
  6955.         WA_Activate,      TRUE,
  6956.     TAG_DONE))
  6957.     )
  6958.     {   DisplayAlert(AT_Recovery, "\0\20\20Saga: Can't open summary window!\0", 24);
  6959.         cleanexit(EXIT_FAILURE);
  6960.     }
  6961.     RectFill(InfoWindowPtr->RPort, 8, 13, 378 - 10, 102 - 6);
  6962.     SetAPen(InfoWindowPtr->RPort, BLACK);
  6963.     SetDrMd(InfoWindowPtr->RPort, JAM1);
  6964.  
  6965.     Move(InfoWindowPtr->RPort, 16, 26);
  6966.     Text(InfoWindowPtr->RPort, line[0][0], strlen(line[0][0]));
  6967.     for (whichhero = 0; whichhero <= HEROES; whichhero++)
  6968.     {   Move(InfoWindowPtr->RPort, 16, 38 + (whichhero * 10));
  6969.         Text(InfoWindowPtr->RPort, line[0][whichhero + 1], strlen(line[0][whichhero + 1]));
  6970.     }
  6971.     Move(InfoWindowPtr->RPort, 16, 29);
  6972.     Draw(InfoWindowPtr->RPort, 368 - 10, 29);
  6973.  
  6974.     while(!done)
  6975.     {   Wait(1L << InfoWindowPtr->UserPort->mp_SigBit);
  6976.         while (MsgPtr = (struct IntuiMessage *) GetMsg(InfoWindowPtr->UserPort))
  6977.         {   class  = MsgPtr->Class;
  6978.             code   = MsgPtr->Code;
  6979.             qual   = MsgPtr->Qualifier;
  6980.             ReplyMsg((struct Message *) MsgPtr);
  6981.             switch(class)
  6982.             {
  6983.             case IDCMP_CLOSEWINDOW:
  6984.                 done = TRUE;
  6985.             break;
  6986.             case IDCMP_RAWKEY:
  6987.                 if (!(qual & IEQUALIFIER_REPEAT) && code < KEYUP && (code < FIRSTQUALIFIER || code > LASTQUALIFIER))
  6988.                 {   done = TRUE;
  6989.                 }
  6990.             break;
  6991.             default:
  6992.             break;
  6993.     }   }   }
  6994.  
  6995.     CloseWindow(InfoWindowPtr);
  6996.     InfoWindowPtr = NULL;
  6997.     clearkybd();
  6998. }
  6999.  
  7000. MODULE SLONG getattackers(SLONG whichhero, SLONG whichcountry)
  7001. {   SLONG whichjarl,
  7002.           totalstrength = 0;
  7003.     FLAG  ok            = FALSE;
  7004.  
  7005.     if (hero[whichhero].alive && !hero[whichhero].routed && hero[whichhero].where == whichcountry)
  7006.     {   hero[whichhero].attacking = TRUE;
  7007.         select_hero(whichhero, FALSE);
  7008.         ok = TRUE;
  7009.         totalstrength += hero[whichhero].strength;
  7010.     }
  7011.     for (whichjarl = 0; whichjarl <= JARLS; whichjarl++)
  7012.     {   if (jarl[whichjarl].alive && jarl[whichjarl].hero == whichhero && !jarl[whichjarl].routed && jarl[whichjarl].where == whichcountry)
  7013.         {   jarl[whichjarl].attacking = TRUE;
  7014.             select_jarl(whichjarl, FALSE);
  7015.             ok = TRUE;
  7016.             totalstrength += jarl[whichjarl].strength;
  7017.     }   }
  7018.     if (ok)
  7019.     {   refreshcounters();
  7020.     }
  7021.     return(totalstrength);
  7022. }
  7023.